mysql主从数据库同步和字符集问题

1.mysql主从数据库同步问题

 
在使用mysql 5.0 主从数据库同步时遇到问题一些问题:
在主从数据库同步时,我们可能会选择哪些数据库要求同步,而那些数据库忽视,这两个功能是靠/etc/my.cnf文件中的两个键名 binlog_do_db 和 binlog_ignore_db 来实现的
binlog_do_db = 填写需要同步的数据库,多个数据库则用‘,’隔开
binlog_ignore_db = 填写不需同步的数据库,多个数据库用 ‘,’隔开
主数据库读取键值,可选择生成数据库日志文件。从服务器根据主服务器日志文件来更新自己的数据库
 
理论上这些都是可行的,然而实际实现中会遇到一些问题,问题如下:
从终端用 mysql -u -p 连接mysql数据库,主服务器执行数据库操作,在binlog_do_db范围内的数据库都会做日志记录,使用mysql提供的api函数用程序连接数据库执行sql语句缺不写入日志
几经周转测试,终于发现将binlog_ignore_db去掉,而且是连键名一起注释掉,这时候主从数据库同步方可成功,API函数进行的数据库操作可以写入日志了
 
这不知是官方bug,还是自己哪方面配置数据库错误。解决方案目前为止只限于此。
                                                                                                                   

 2.mysql字符集问题 (从数据库安装着手)

数据库链接命令行中输入 
show variables like 'char%';
得到以下结果
+--------------------------+----------------------------+
| Variable_name                | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |            客户端字符集
| character_set_connection | utf8                       |        连接字符集
| character_set_database   | utf8                       |         数据库字符集
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |            取得结果字符集
| character_set_server     | utf8                       |            服务器字符集
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.28 sec)

这个就是字符集表了

我们如果想取出的数据不是乱码 那么 character_set_results 的value的结果就必须于程序运行中应用的字符集相符,要不然显示就是乱码。
如果想插入到数据库中的数据不是乱码,那么就要求连接的字符集于程序中sql语句的字符集要相同。

问题1:
为什么有时候我们用终端登录的时候就不是乱码,但是用程序进行sql操作的时候就出现乱码了呢。
answer:因为程序链接的时候用的是动态链接库连接数据库的,而终端用的mysql_client自己安装的程序,这两个字符集可能会不相同。
问题2:
为什么程序运行有一段时间后就开始出现乱码了,插入与取出数据都是乱码了。
answer:connection有一个时间,超时就会重新连接 ,有两种设置方法 
    2.1 执行sql语句 set names 'utf8' 2
    2.2 mysql_options(ledMysql, MYSQL_SET_CHARSET_NAME, "utf8");
第一种方法只是暂时有效,第二种方法再每次重连的时候都会设置字符集为utf8

mysql带来的问题主要是字符集的问题。其实有一种更绝的方法就是在安装数据库的时候只保留utf8字符集那不管怎么连接都不会出现乱码了。

3. 编译问题

./configure --prefix=/usr/local/mysql --sysconfdir=/etc --localstatedir=/var/lib/mysql --enable-local-infile --enable-assembler --with-charset=utf8  --with-big-tables  --with-plugin-partition --with-plugin-federated

 

如果是非编译版本,安装的时候请注意使用,否则可能会安装到错误的位置

/usr/local/mysql/bin/mysqld_install --basedir=/usr/local/mysql --ldata=/var/lib/mysql

 

一般情况下都是不能正常链接数据库,错误提示一般为:

ERROR 2002: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) 

其实网上大家问的最多的都是整个问题,说什么链接不到mysqld.sock,其实大家不妨看看mysql的错误日志就明白怎么回事,我这里的错误日志是在

/var/lib/mysql/*.err 你会发现mysql只所以不能启动,是因为/var/lib/mysql的权限不允许mysql服务访问,英文mysql默认是调用mysql用户来启动服务的,好了,既然知道是什么原因找到不能启动,那就简单了。我们只要

chown -R mysql:mysql /var/lib/mysql 就行,如果还是启动不了,再慢慢调试权限,反正一般启动不了都是权限的问题。

如果大家还是不能启动不了的话,那就用我的比较繁琐的权限的设置,反正我每次都是这么做的,一般不会有问题,见下:

 

chown -R root /usr/local/mysql  
chgrp -R mysql /usr/local/mysql  
chown -R root /usr/local/mysql/bin  
chgrp -R mysql /usr/local/mysql/bin  
chgrp -R mysql /var/lib/mysql  
chmod 777 /var/lib/mysql  
chown -R root /var/lib/mysql/mysql  
chgrp -R mysql /var/lib/mysql/mysql  
chmod 777 /var/lib/mysql/mysql  
chown -R root /var/lib/mysql/mysql/*  
chgrp -R mysql /var/lib/mysql/mysql/*  
chmod 777 /var/lib/mysql/mysql/*  
chmod 777 /usr/local/mysql/lib/mysql/libmysqlclient.a

 

4.mysql client 字符集设置

4.1终端访问:

通常终端访问只需在/etc/my.cnf中将default-charcter-set=utf8就不会出现乱码

4.2程序连接:

用程序连接数据库的时候调用的是动态链接库libmysqlclient.so or libmysqlclient.a

问题解析:向默认字符集为utf8的数据表插入utf8数据前没有设置连接字符集,查询时设置字符集为utf8,导致的查询乱码。

      4.2.1在插入的时候根据mysql服务的默认设置,如果不设置字符集那么 charater-set-client connection result 均为latinl字符集。所以在插入的时候数据会经过以下变换 utf8->latinl=>utf8的字符集转换过程,这一过程每个插入的汉字会经历程序到动态库,所以字符都会从原来的3个字节(程序utf8)变成6个字节(动态库latinl)保存。

      4.2.2在查询时许将字符集转换成results所需的字符集,如果results字符集与程序所需不同将出现乱码。

4.3 对于使用mysql c api时

      使用mysql api时初始化数据库句柄后马上用 mysql_option设定MYSQL_SET_CHARASET_NAME属性为utf8,这样就不需要使用set names语句指定连接字符集。mysql_ping重新断开连接时也会吧连接字符重置为utf8,不需每次重连都set names

 

5. mysql API PHP

    一般页面的PHP程序运行时间较短,在连接到数据库后用set names语句设置一次连接字符即可。但当使用长连接时,请注意保持通畅并在端来连接后再次用set names设置连接字符集。

 

 

ATTENTION:

    my.cnf 中的default_character_set 设置只影响在终端这种用mysql命令连接服务器时连接字符集,不会对使用libmysqlclient库连接mysql的应用程序产生任何作用。

 

本文转自holy2009 51CTO博客,原文链接:http://blog.51cto.com/holy2010/536222

上一篇:java中的移位运算符:<<,>>,>>>总结(转)


下一篇:如何使用迁云工具迁移服务器到阿里云?