有意思的事情每天都有,最近一个客户的公司的PG数据库在运行中,出现了一个问题,客户在对数据进行排序的过程中,发现数据虽然一致,但两个存储同样数据的数据库,在进行语句查询的时候,给出的结果不同,基于他们只取结果集的前两条,导致同样的数据库表,同样的数据,最终在界面上给客户展示的数据不同。
开发人员随即提出,之前在MySQL 上从未发生这样的问题,而基于一些政府机构的要求,不能使用MySQL 而将应用程序转移到了PostgreSQL上就问题百出,随即甩出不负责的一句, MySQL就是比 PostgreSQL 要稳定,出问题少。
基于客户的隐私,这里只能用测试机和自己的测试数据代替,参见上图,的确两个都是PG的数据库,在输入同样的数据后,在对中文字符进行排序后,发现次序不同。
基于这个问题的情况看,大概率是字符集及字符集的排序不同导致,但是客户的开发人员,咬定说一起装的,没有分别,生产数据库不能乱动,就是PG的问题等。
这里沟通,仅仅针对两个系统进行参数和系统的关于字符集的参数的搜取,不会对系统进行任何的改变和设置。
1 查看操作系统当前的字符集支持,通过locale -a 针对两个数据库系统的操作系统支持的字符集进行了检查,明显两个系统支持的字符集的数量非常不一样。
当然这里,并不是产生问题的关键,但两个系统的字符集支持,并非像开发人员提出的,两个系统一模一样,基于这个部分后,我们找到突破口,将结果展示,并告知,排序的不同,与数据库的字符集有关,基于之前提出的两个系统一模一样,目前看并不是这样。
对方则同意给我们相关的数据库账号,进行进步一的分析。这里我们针对数据库中客户登陆的字符集两个物理数据库中的逻辑库的 encoding 都进行了校对,两个数据库在这里是一致的。
select datname,datcollate,datctype from pg_database where datname = 'test';
到了这里,明显是datcollate 的是不一样的,但开发提出为什么会不一样。
postgres=# select datname,datcollate,datctype from pg_database where datname = 'test';
datname | datcollate | datctype
---------+------------+------------
test | zh_CN.utf8 | zh_CN.utf8
postgres=# select datname,datcollate,datctype from pg_database where datname = 'test';
datname | datcollate | datctype
---------+------------+------------
test | en_US.utf8 | en_US.utf8
然后针对疑问,我们对于数据库服务器中的配置文件进行了检查,明显两个数据库在初始化的时候,就有不同,至少在蓝色图中的数据库,初始化的时候,的配置项 locale=zh_CN.UTF-8 当然这个我们是无法进行复原数据库初始化的场景,但从配置文件中,locale 的部分应该不是默认的,而白色的数据库的locale应该是没有动过的,按照默认进行设置。
同时在我们通过pg_admin 想查看数据库创建语句的尝试中,发现系统直击报错。
而另一个数据库本身可以直接显示数据库的默认建库的语句。
最后我们找到他出问题的语句,将排序后面添加了对方数据库的 collate 在此核验数据库的结果,完全一致。
开发人员问,那这我也不能带着后面的部分去执行呀,我还的改程序,你有没有办法?
此时我看向那个口出狂言的开发人员,MySQL 比 PostgreSQL稳定不稳定我不清楚,但我看你们的稳定性一定没有PostgreSQL的稳定性高。
顺便买本书,好好学学吧 !
另外建议某些开发的同学,不会可以,但做一个数据库“种族主义”者 就不大好了!!!!!!!!!!!