Ale*_*lex 6 postgresql replication postgresql-9.1
我们在主服务器上的 Ubuntu Linux 12.04 上使用 PostgreSQL 9.1.7,在副本服务器上的 FreeBSD 9.0-RELEASE 上使用 PostgreSQL 9.1.7。副本服务器和主服务器对同一 SQL 查询返回不同的结果。查询计划显示使用索引(BTree 索引,我们根本不使用哈希索引)来获取结果,因此看起来索引在副本服务器上处于不一致或不完整状态。主服务器上的查询:
db1=# select id from users where email='xxxx@xxxx.net';
id
---------
1698116
(1 row)
db1=#
Run Code Online (Sandbox Code Playgroud)
在副本服务器上的查询:
db1=> select id from users where email='xxxx@xxxx.net';
id
----
(0 rows)
db1=> select created_at from users where id=1698116;
created_at
----------------------------
2013-03-04 10:40:05.221214
(1 row)
db1=>
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,副本数据库已经包含一个具有正确 ID 的用户,因此数据已就位,但由于某种原因尚未编入索引。我们仔细检查了副本是否处于接收/重新应用状态,因此这不是暂时中断。用户从未被编入索引。我们也曾在 CentOS 5.6 上使用 PostgreSQL 9.0 遇到过类似问题,因此我们认为这不是 FreeBSD 或 PostgreSQL 9.1 特定的问题。
我们使用副本服务器运行大量繁重的 SQL 查询,这可能是问题的根源吗?无论如何,我们如何才能有效地检测和防止将来发生此类情况?副本今天没有停机,日志中没有任何错误行,所以我们只是偶尔检测到这种不一致。
假设数据库的语言环境en_GB.UTF-8在 Ubuntu(主)和 FreeBSD(从)中,我相信排序语义的差异可能会导致索引在从上无法使用的事实。
以下是它们如何以不同方式排序的示例:
在 Ubuntu 12.04 上:
$ export LANG=en_GB.UTF-8
$ cat >file
"0102"
0102
$ sort file
0102
"0102"
Run Code Online (Sandbox Code Playgroud)
在 FreeBSD 9.0-RELEASE 上:
$ export LANG=en_GB.UTF-8
$ cat >file
"0102"
0102
$ sort file
"0102"
0102
Run Code Online (Sandbox Code Playgroud)
这给出了同一区域不同的订单两个字符串"0102"和0102(即使他们甚至不包含US-ASCII字符集以外的任何字符...)
这是我建议您在自己的数据集上尝试的测试:
在主人身上:
$ psql -d dbname -Atc 'select email from users' | LC_COLLATE=en_GB.UTF-8 >email.master
Run Code Online (Sandbox Code Playgroud)
在奴隶上:
$ psql -d dbname -Atc 'select email from users' | LC_COLLATE=en_GB.UTF-8 >email.slave
Run Code Online (Sandbox Code Playgroud)
现在比较email.master和email.slave与差异或CMP。我怀疑你会发现它们并不相同。在这种情况下,它表明不能使用索引副本,因为它在主服务器上的构建规则与从服务器上的扫描规则不同。
| 归档时间: |
|
| 查看次数: |
1235 次 |
| 最近记录: |