Chinaunix首页 | 论坛 | 博客
  • 博客访问: 29315012
  • 博文数量: 2065
  • 博客积分: 10377
  • 博客等级: 上将
  • 技术积分: 21525
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-04 17:50
文章分类

全部博文(2065)

文章存档

2012年(2)

2011年(19)

2010年(1160)

2009年(969)

2008年(153)

分类: Mysql/postgreSQL

2009-03-04 12:57:58

与其放弃自己,不相信自己还不如让自己真的强起来。克服自卑的心理与不自信的心理。克服浮躁的心理,告诉自己忍一忍就可能会找到成功的大道了!静下心来去思考。
1.我用了三台虚拟机然后用netstat -na 可以查看了MYSQL的3306端口是正常启动了的。但是如何来进入到MYSQL中呢?我不知道在哪里可以执行 ./mysql -uroot -p操作哦!没办法上网查了一下发现了可以这样来做的
的shell<< ps aux | grep mysql
会得到如下的信息:
root      2801  0.0  1.1 55976 1380 ?        S    Mar02   0:00 /bin/sh /data/mys
ql/bin/mysqld_safe --datadir=/data/mysql/data --pid-file=/data/mysql/data/master
.pid
mysql     2962  0.0 21.6 264480 26544 ?      Sl   Mar02   0:36 /data/mysql/bin/m
ysqld --basedir=/data/mysql --datadir=/data/mysql/data --user=mysql --log-error=
/data/mysql/data/master.err --pid-file=/data/mysql/data/master.pid --socket=/tmp
/mysql.sock --port=3306
可以从这些信息中发现我们所需要的信息了:原来MYSQL跑到了这个目录下面的:/data/mysql/bin
可以查看到MYSQL的相关信息。
现在就可以输入如下的命令了:./mysql -uroot -p
2. 开始测试集群服务器配置是否成功
我在主机中新建一个表然后往里面插了一条新记录之后会发现在两台从机中能够看到所插入的记录值啊!
这就说明了主机与两台从机之间是能够做到同步的哦。数据同步!
但是:如果说在S1或S2中新加或修改或删除数据之后,我们的主机是不会有什么变化的哦!只有在主机中添加数据才会带动我们的从机的呢!
对了,我们在主服务器配置中会有一个新的配置:指定到底是哪个数据库会进行复制操作的。
这就是说:我们在进行数据操作的时候只能是针对这个数据库进行的。其他 的库是没有用的哦。就算你现在新创建了一个新的数据库了然后从机中是没有这个库 的哦!

哈哈。我查了一下在主机中用户表中会有两个新用户,分别的HOST值指向了91与92这就意味着,这台主机是能够接受来自91 92这两台从机的访问的哦!
grant replication slave on *.* to 'repuser'@'%' identified by '123456';
需要执行这条命令可以从机用的。


3.简单讲述一下MYSQL中的主从配置应用
主服务器将更新写入二进制日志文件,并维护日志文件的一个索引以跟踪日志循环。当一个从服务器连接到主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知下一次更新。

为什么使用主从复制?

1、主服务器/从服务器设置增加了健壮性。主服务器出现问题时,你可以切换到从服务器作为备份。

2、通过在主服务器和从服务器之间切分处理客户查询的负荷,可以得到更好的客户响应时间。但是不要同时在主从服务器上进行更新,这样可能引起冲突。

3、使用复制的另一个好处是可以使用一个从服务器执行备份,而不会干扰主服务器。在备份过程中主服务器可以继续处理更新。

MySQL数据库支持数据库的主从复制功能,使用主数据库进行数据的插入、删除与更新操作,而从数据库则专门用来进行数据库查询,这样就可以将更新操作与查询操作分离到不同的数据库上,从而提高查询的效率。


2.主数据库配置
    MySQL任何一台数据库服务器都可以作为主数据库服务器,我们只需要简单的修改配置文件就可以使之成为主数据库服务器。我们打开MySQL的配置文件 (对于windows就是MySQL安装目录下的my.ini文件,对于linux通常就是/etc/my.cnf文件),我们在配置文件中加入如下两 行:
server-id = 1
log-bin=mysql-bin
    注意,MySQL进行主从复制是通过二进制的日志文件来进行,所以我们必须开启MySQL的日志功能,即我们上面的log-bin,同时每一台数据库服务 器都需要指定一个唯一的server-id,通常主数据库服务器我们指定为1。主数据库服务器的配置就是如此了,然后我们还需要给主数据库授予一个可以进 行复制的用户,命令如下:
grant replication slave on *.* to 'repuser'@'%' identified by '123456';
    replication slave是MySQL数据库中表示复制的权限名称,repuser则是表示从数据库服务器登陆到主数据库服务器时用到的用户名称,123456表示登陆 密码。这样,我们就在主数据库服务器上创建了一个可以进行复制的用户账号了。然后我们启动主数据库服务器就可以了。

3.从数据库配置
从数据库服务器的配置稍微多一点,主要也是修改MySQL的配置文件,加入如下行:
server-id=2
log-bin=mysql-bin     --在从服务器上启动日志记录,不是必须,但是官方建议
master-host=主机      --主数据库服务器的IP地址
master-user=用户名    --执行复制的用户名称,就是grant的用户
master-password=密码  --复制用户的密码,就是grant的用户密码
master-port=端口      --主数据库服务器的端口,默认是3306
    相关的配置参数意义已做了说明,主要就是多了配置主数据库服务器上的复制账号的信息。然后我们启动从数据库服务器,注意启动从数据库服务器后,并没有启动复制线程,我们需要在命令行中执行如下命令来启动复制功能:
slave start
启动后,我们就可以通过如下命令来查看复制的状态了:
show slave status \G;             #这个命令是在mysql中命令行敲进来的哦!
    然后我们就可以看到系统的输出,第一个就是Slave_IO_State,它的值通常就是Waiting for master to send event,然后我们也还可以看到我们刚才配置的主数据库服务器的IP地址、复制账号等信息。
我们还可以在从数据库服务器上动态的改变对主数据库的配置信息,通过如下命令来进行:
CHANGE MASTER TO MASTER_HOST=’主数据库服务器的IP地址’, MASTER_PORT=3306,MASTER_USER=’主数据库上的复制帐号’, MASTER_PASSWORD=’密码’;

#从服务器的配置:复制主服务器,帐号,密码,库,表
master-host = 192.168.100.90
master-user =repuser             ‘在user表中查询出来的用户名
master-password =123456
#Replicate_Do_DB = mytianya      '指定的可复制数据库
replicate-do-db=tianya_test      '就只有这个数据库能够进行复制
#replicate-wild-do-table = mytianya.tb_user_space
#存放日志文件
log-bin=/data/mysql/log/mysql-bin
#服务ID号,一组服务器的ID不能相同
server-id       = 2

第二台从服务器中的配置文件内容:
master-host = 192.168.100.90
master-user =repuser
master-password =123456
replicate-do-db=tianya_test
#Replicate_Do_DB = mytianya
#replicate-wild-do-table = mytianya.tb_user_space
#存放日志文件
log-bin=/data/mysql/log/mysql-bin
#服务ID号,一组服务器的ID不能相同
server-id       = 3



4.启动与监控
1)监控主数据库服务器的状态
我们可以通过showmaster status来查看主数据库服务器的状态,它的输出如下:
这个命令是在MYSQL命令行中所输入进来的!
+------------------+----------+--------------+------------------+
| File            | Position    | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 |   370558 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

    其中File是表示日志记录的文件,而Position则是表示当前日志在文件中的位置,这个也是从数据库服务器上执行复制操作必须的标识,后面的两个字段分别表示要记录的数据库名称和不需要记录的数据库名称,我们也可以在配置文件中进行配置。

2)监控从数据库服务器的状态
我们可以通过show slave status来查看从数据库服务器的状态,它的基本输出如下:
+----------------------------------+---------------+-------------+-------------+---------------+------------------+---------------------+-----------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+
| Slave_IO_State                   | Master_Host   | Master_User | Master_Port | Connect_Retry | Master_Log_File  | Read_Master_Log_Pos | Relay_Log_File        | Relay_Log_Pos | Relay_Master_Log_File | Slave_IO_Running | Slave_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Master_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Master_SSL_Allowed | Master_SSL_CA_File | Master_SSL_CA_Path | Master_SSL_Cert | Master_SSL_Cipher | Master_SSL_Key | Seconds_Behind_Master |
+----------------------------------+---------------+-------------+-------------+---------------+------------------+---------------------+-----------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+
| Waiting for master to send event | 172.16.11.221 | repuser     |        3306 |            60 | mysql-bin.000003 |              370558 | WEB2-relay-bin.000206 |         12251 | mysql-bin.000003      | Yes              | Yes               |                 |                     |                    |                        |                         |                             |          0 |            |            0 |              370558 |           12251 | None            |                |             0 | No                 |                    |                    |                 |                   |                |                     0 |
+----------------------------------+---------------+-------------+-------------+---------------+------------------+---------------------+-----------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+
1 row in set (0.00 sec)

    我们看到红色的部分,分别表示的是Master_Log_File和Read_Master_Log_Pos,即主数据库服务器上的日志文件和要读取的主 数据库服务器上的日志的位置,通常这个Read_Master_Log_Pos是和主数据库服务器上的Position是一致的,当然这个是指同步以后 的,如果从数据库服务器还没有同步完毕,那么这个值通常比主数据库服务器上的要小。
    如果从数据库服务器在同步的过程中出现了问题,那么我们可以通过reset slave来重置从数据库服务器的复制线程,从数据库服务器上的通常操作命令有:
Slave start; --启动复制线程
Slave stop; --停止复制线程
Reset slave; --重置复制线程
Show slave status; --显示复制线程的状态
Change master to; --动态改变到主数据库的配置

如果说:在Mysql> slave stop  的话就会停止这台从机了。我测试了这个时候就不会进行同步复制操作!
我在主机上删除掉一个数据表那这台从机就不会自动删除掉。然后重启一下就又可以实现同步复制操作了!
[如何才能提高自己的编程能力。这个是当务之急的!当务之急是能够静下心来思考要做的事情!]

SHELL<< /data/mysql/bin/mysql -uroot -e "slave start"
我们在SHELL中直接输入如上的系统命令就可以将这台从机与主机之间的复制关系给关闭掉了!

三.验证是否配置正确
登录从服务器输入如下命令:
mysql> show slave status\G;
确如如下行一致:
Waiting for master to send event
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

只要在从服务器上的mysql命令行先键入slave stop;然后复制数据库文件,复制好了,再在mysql命令行键入slave start;启动从服务器,这样就即备份了数据有保证了数据完整性,而且整个过程中主服务器的mysql无需停止。


++修改配置需要注意
需要删除从服务器上的/var/lib/mysql/master.info文件

++主服务器上的相关命令
show master status
show slave hosts
show logs
show binlog events
purge logs to ‘log_name’
purge logs before ‘date’
reset master(老版本flush master)
set sql_log_bin=

++从服务器上的相关命令
slave start
slave stop
SLAVE STOP IO_THREAD //此线程把master段的日志写到本地
SLAVE start IO_THREAD
SLAVE STOP SQL_THREAD //此线程把写到本地的日志应用于数据库
SLAVE start SQL_THREAD
reset slave
SET GLOBAL SQL_SLAVE_SKIP_COUNTER
load data from master
show slave status(SUPER,REPLICATION CLIENT)
CHANGE MASTER TO MASTER_HOST=, MASTER_PORT=,MASTER_USER=, MASTER_PASSWORD= //动态改变master信息
PURGE MASTER [before 'date'] 删除master端已同步过的日志

++产生了mysql-bin.00000x文件可以删除
reset master; #`

++同步出错时,如果被同步语句确定在从库上可以被忽略
slave stop;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n;
slave start;
# 看show slave status \G中的Seconds_Behind_Master: 0为正常

附件1:检查从服务器状态脚本
#!/bin/bash
#/blog.zhangjianfeng.com/sh/mysql/CheckMysqlStatus.sh

DATE=`date +%Y%m%d-%H%M%S`
LOGPATH=/blog.zhangjianfeng.com/logs/Mysql
LOG=$LOGPATH\/SlaveStatus_log_$DATE
IP_LIST=(219.xx.xx.xx 60.xx.xx.xx)

if [ ! -d $LOGPATH ]
then
mkdir -p $LOGPATH
fi

checkstatus()
{
for i in ${IP_LIST[*]}
do
echo -e “\n====== Checking $i ======”
ssh $i “mysql -ppassword -e \”show slave status\\G \”"
done
}

case “$1″ in

checkselect)
checkselect
;;
*)
checkstatus
;;
esac

附件2:自动同步从服务器数据
#!/bin/bash
now=`date +%y%m%d-%H%M`
date=`date +%Y%m%d`
srcdir=/blog.zhangjianfeng.com/backup/mysql/forscript/$date/
DBNAME=ptv
DSTDIR=/blog.zhangjianfeng.com/tmp/mysql/$date/
IP_LIST=(xx.xx.xx.13 xx.xx.xx.14 xx.xx.xx.15)

[ ! -d $srcdir ] && mkdir -p $srcdir

savelog()
{
echo -e “\nSaving error logs,pls wait…”
/blog.zhangjianfeng.com/sh/mysql/CheckMysqlStatus.sh wlog
}

start ()
{

#savelog

### MYSQLDUMP & GZIP ###
echo -e “\eMysqlDump running, pls wait…”
cd $srcdir
rm -f $srcdir/*
mysqldump -ppassword –master-data $DBNAME > $DBNAME.$date
SRCFILEMD5=`md5sum $DBNAME.$date|awk ‘{print $1}’ `
gzip $DBNAME.$date
echo “MysqlDump and GZIP done!”

### transfer
echo “starting transfer…”
ssh $DSTIP ” [ -d $DSTDIR ] && rm -rf $DSTDIR ”
ssh $DSTIP ” mkdir -p $DSTDIR ”
scp $srcdir$DBNAME.$date\.gz $DSTIP:$DSTDIR
echo “Transfer done…”

ssh $DSTIP “cd $DSTDIR && gzip -d $DBNAME.$date\.gz”
DSTFILEMD5=` ssh $DSTIP “cd $DSTDIR && md5sum $DBNAME.$date” |awk ‘{print $1}’`

echo $SRCFILEMD5 $DSTFILEMD5

if [ ! $SRCFILEMD5 == $DSTFILEMD5 ]
then
echo “Transfer failed, pls check!”
exit 999
fi
echo “MD5 check passed”

ssh $DSTIP “mysql -ppassword -A -e \”slave stop\” && mysql -ppassword $DBNAME < $DSTDIR$DBNAME.$date && mysql -ppassword -A -e \”slave start\”"

}

check()
{
echo -e “\n`date +%Y.%m.%d\ %R:%S\ start…`”
mysql -ppassword -e “use $DBNAME; insert into slavetest(field1) values (\”slavetest-$now\”);”
echo MasterDB
mysql -ppassword -e “select * from $DBNAME.slavetest order by id desc limit 10 ”
sleep 10

for i in ${IP_LIST[*]}
do
echo $i
ssh $i “mysql -pletv0580 -e \”select * from $DBNAME.slavetest order by id desc limit 10 \”"
done

echo -e “\n`date +%Y.%m.%d\ %R:%S\ END!`”
}

checkandmail()
{
logfile=/blog.zhangjianfeng.com/tmp/checkallslavedbstatus
> $logfile
echo -e “\n`date +%Y.%m.%d\ %R:%S\ start…`” >>$logfile
mysql -e “use $DBNAME; insert into slavetest(field1) values (\”slavetest-$now\”);” -ppassword
sleep 10
echo ==$DSTIP1== >>$logfile
ssh $DSTIP1 “mysql -e \”select * from $DBNAME.table1 order by id desc limit 1 \”" >>$logfile
echo -e “`date +%Y.%m.%d\ %R:%S\ END!`” >>$logfile
cat $logfile | mail -s “Check all SlaveDB status every week.” admin@zhangjianfeng.com
}

case $1 in

xx.xx.xx.13|13)
DSTIP=xx.xx.xx.13
start
;;

xx.xx.xx.14|14)
DSTIP=xx.xx.xx.14
start
;;

xx.xx.xx.15|15)
DSTIP=xx.xx.xx.15
start
;;

check)
check
;;

checkandmail)
checkandmail
;;

*)
echo “$0 {SLAVEIP|check}”
;;

esac



A为主机,B为备份机, 同为双网卡,而且可以通过内网相连

A 内网IP : 192.168.195.28

B 内网IP : 192.168.195.30

数据库版本(5.0.22),目录,初始的库,表 两台机器是一样的

需要备份的库     ad_data , alexa_info , log_db , oblog , union_db , zm0061_db

不需要备份的库     mysql , test

正述

1. 在主机上添加帐号 mysqlrepl 为备份帐号

GRANT REPLICATION SLAVE ON *.* TO 'mysqlrepl'@'192.168.195.30' IDENTIFIED BY '123456789';

如果是4.02版本以前用

GRANT FILE ON *.* TO 'mysqlrepl'@'192.168.195.30' IDENTIFIED BY '123456789';

然后让两台机器的数据库都 shutdown ,锁表也成,但为了直达目的,咱没玩那么高深 :)

2. 修改 A 机器上的 /data/8le8le/database/statusdb/cnf/my-status.cnf

# 日志的名称
log-bin=mysql-bin
# 主服务器ID
server-id=1
# 需要备份的库
binlog-do-db=ad_data
binlog-do-db=alexa_info
binlog-do-db=log_db
binlog-do-db=oblog
binlog-do-db=union_db
binlog-do-db=zm0061_db
# 忽略的数据库
binlog-ignore-db=mysql
binlog-ignore-db=test


3. 修改 B 机器上的 /data/8le8le/database/statusdb/cnf/my-status.cnf

# 日志的名称
log-bin=mysql-bin
# 从服务器ID
server-id=2
# 主服务器的IP地址或者域名
master-host=192.168.195.28
# 主数据库的端口号
master-port=30001
# 同步数据库的用户
master-user=mysqlrepl
# 同步数据库的密码
master-password=123456789
# 如果从服务器发现主服务器断掉,重新连接的时间差
master-connect-retry=60
# 需要备份的库
replicate-do-db=ad_data
replicate-do-db=alexa_info
replicate-do-db=log_db
replicate-do-db=oblog
replicate-do-db=union_db
replicate-do-db=zm0061_db
# 忽略的数据库
replicate-ignore-db=mysql
replicate-ignore-db=test


4. 启动主 服务器     启动 从服务器

从B机器登上数据库
mysql> show slave status\G;
其中两行显示
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes


MySQL同步机制基于master把所有对数据库的更新、删除等)都记录在二进制日志里。因此,想要启用同步机制,在master就必须启用二进制日 志。每个slave接受来自master上在二进制日志中记录的更新操作,因此在slave上执行了这个操作的一个拷贝。应该非常重要地意识到,二进制日 志只是从启用二进制日志开始的时刻才记录更新操作的。所有的 slave必须在启用二进制日志时把master上已经存在的数据拷贝过来。如果运行同步时slave上的数据和master上启用二进制日志时的数据不 一致的话,那么slave同步就会失败。把master上的数据拷贝过来的方法之一实在slave上执行 LOAD DATA FROM MASTER 语句。不过要注意,LOAD DATA FROM MASTER 是从MySQL 4.0.0之后才开始可以用的,而且只支持master上的 MyISAM 类型表。同样地,这个操作需要一个全局的读锁,这样的话传送日志到slave的时候在master上就不会有更新操作了。当实现了自由锁表热备份时(在 MySQL 5.0中),全局读锁就没必要了。由于有这些限制,因此我们建议只在master上相关数据比较小的时候才执行 LOAD DATA FROM MASTER 语句,或者在master上允许一个长时间的读锁。由于每个系统之间 LOAD DATA FROM MASTER 的速度各不一样,一个比较好的衡量规则是每秒能拷贝1MB数据。这只是的粗略的估计,不过master和slave都是奔腾700MHz的机器且用 100MBit/s网络连接时就能达到这个速度了。slave上已经完整拷贝master数据后,就可以连接到master上然后等待处理更新了。如果 master当机或者slave连接断开,slave会定期尝试连接到master上直到能重连并且等待更新。重试的时间间隔由 --master-connect-retry 选项来控制,它的默认值是60秒。每个slave都记录了它关闭时的日志位置。msater是不知道有多少个slave连接上来或者哪个slave从什么 时候开始更新。

MySQL同步功能由3个线程(master上1个,slave上2个)来实现。执行 START SLAVE 语句后,slave就创建一个I/O线程。I/O线程连接到master上,并请求master发送二进制日志中的语句。master创建一个线程来把日 志的内容发送到slave上。这个线程在master上执行 SHOW PROCESSLIST 语句后的结果中的 Binlog Dump 线程便是。slave上的I/O线程读取master的 Binlog Dump 线程发送的语句,并且把它们拷贝到其数据目录下的中继日志(relay logs)中。第三个是SQL线程,salve用它来读取中继日志,然后执行它们来更新数据。如上所述,每个mster/slave上都有3个线程。每个 master上有多个线程,它为每个slave连接都创建一个线程,每个slave只有I/O和SQL线程。在MySQL 4.0.2以前,同步只需2个线程(master和slave各一个)。slave上的I/O和SQL线程合并成一个了,它不使用中继日志。slave上 使用2个线程的优点是,把读日志和执行分开成2个独立的任务。执行任务如果慢的话,读日志任务不会跟着慢下来。例如,如果slave停止了一段时间,那么 I/O线程可以在slave启动后很快地从master上读取全部日志,尽管SQL线程可能落后I/O线程好几的小时。如果slave在SQL线程没全部 执行完就停止了,但I/O线程却已经把所有的更新日志都读取并且保存在本地的中继日志中了,因此在slave再次启动后就会继续执行它们了。这就允许在 master上清除二进制日志,因为slave已经无需去master读取更新日志了。执行 SHOW PROCESSLIST 语句就会告诉我们所关心的master和slave上发生的情况。


OK!也就是那么一回事了。现在来分析一下如何来实现我自己的切换过来的功能!










阅读(1311) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~