Linux企业化运维
实验所用系统为Redhat-rhel7.6。
目录
Linux企业化运维–(5)mysql之编译、主从复制、主从(主)从复制+GTID、半同步
一、Mysql编译
1、下载软件
https://www.mysql.com
或者
lftp 172.25.254.250
> get mysql-boost-5.7.31.tar.gz
2、解压编译
对压缩包进行解压,并对mysql进行源码编译,其中需要下载依赖才能编译成功。
tar zxf mysql-boost-5.7.31.tar.gz
cd mysql-5.7.31/
yum install -y cmake
yum install -y ncurses-devel
yum install gcc-c++ -y
yum install bison -y
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/data/mysql -DMYSQL_UNIX_ADDR=/data/mysql/mysql.sock -DWITH_INNOBASE_STORAGE_ENGINE=1 -DSYSCONFDIR=/etc -DENABLED_LOCAL_INFILE=1 -DWITH_EXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_unicode_ci -DWITH_BOOST=/root/mysql-5.7.31/boost/boost_1_59_0
[注意] 如果没有一次性cmake成功,则删除CMakeCache.txt,重新cmake
参数含义
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql ##指定软件的安装路径
-DMYSQL_DATADIR=/data/mysql ##指定MySQL数据库数据文件的存储路径,这一选项在MySQL服务启动时可以通过datadir参数进行设置
-DMYSQL_UNIX_ADDR=/data/mysql/mysql.sock ##指定套接字文件的存储路径,默认是在/tmp/mysql.sock目录下,这一选项可以在MySQL服务启动时通过socket参数进行设置
-DWITH_INNOBASE_STORAGE_ENGINE=1 ##静态编译存储引擎
-DSYSCONFDIR=/etc ##指定MySQL参数文件的默认路径,这一选项可以在MySQL服务启动时通过defaults-file参数进行设置
-DENABLED_LOCAL_INFILE=1 ##是否允许从客户端本地加载数据到MySQL服务端,专用于load data infile语句,默认是不允许的
-DWITH_EXTRA_CHARSETS=all ##指定附加支持的字符集,默认是all
-DDEFAULT_CHARSET=utf8mb4 ##指定MySQL服务的默认字符集
-DDEFAULT_COLLATION=utf8mb4_unicode_ci ##指定MySQL服务的默认校对规则
-DWITH_BOOST=/root/mysql-5.7.31/boost/boost_1_59_0 ##安装位置与数据位置
接下来进行make
和make install
,并修改环境变量使其生效。
make ##make -j4 4核cpu并行编译,但不建议在虚拟机,会内存溢出
make install
cd
vim .bash_profile ##添加环境变量
///
PATH=$PATH:$HOME/bin:/usr/local/lnmp/php/bin:/usr/local/mysql/bin
///
source .bash_profile ##生效
make
时间比较久。
创建mysql
的数据目录,并设定为某一用户的所属人、所属组以保证其执行权限,因此建立该用户。同时拷贝启动脚本,使mysql可全局使用,然后开启服务。
useradd -M -d /data/mysql -s /sbin/nologin mysql
mkdir /data/mysql -p ##创建数据目录
chown mysql.mysql /data/mysql
cd /usr/local/mysql/support-files
cp mysql.server /etc/init.d/mysqld ##拷贝启动脚本
/etc/init.d/mysqld start ##开启
3、修改配置文件及初始化
修改配置文件,设定mysql的数据目录,套接字文件的存储路径,错误日志与pid文件。之后进行初始化,获得一个随机密码用于登陆数据库,使用该密码进行安全配置,修改密码。
cd /etc/
vim my.cnf ##修改配置
///
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
[mysqld_safe]
log-error=/data/mysql/mysqld.log
pid-file=/var/run/mysqld.pid
///
cd /etc/my.cnf.d/
mysqld --initialize --user=mysql ##初始化数据库,此时会有一个初始密码,先记住
mysql_secure_installation ##安全配置向导,修改密码(enter,enter,y,y,y,y)
[注意] 要是密码输入以之后没有成功的话,需要
rm -fr /data/mysql/*
再进行mysqld --initialize --user=mysql生成一个密码
启动服务/etc/init.d/mysqld start
重新进行mysql_secure_installation
4、mysql图形化管理
安装一个mysql
图形化管理工具,解压并将其移动到nginx
服务的发布目录下,启动php-fpm
,修改配置文件使nginx识别php格式的发布文件,重启nginx,查看是否存在mysql进程。
lftp 172.25.254.250
> get phpMyAdmin-5.0.2-all-languages.zip ##MySQL图形化管理工具
unzip phpMyAdmin-5.0.2-all-languages.zip
mv phpMyAdmin-5.0.2-all-languages /usr/local/nginx/html/phpadmin
systemctl enable --now php-fpm.service
vim /usr/local/nginx/conf/nginx.conf
///
server {
listen 80;
server_name localhost;
location / {
root html;
index index.php index.html index.htm;
}
}
///
nginx -s reload
php -m | grep mysql
在PHP
中设置默认MySQL套接字
,注意要与mysql中的设定一致,重启php-fpm
,便可以在浏览器登陆数据库进行操作。可以在mysql
中查看是否插入成功。
vim /usr/local/lnmp/php/etc/php.ini ##在PHP中设置默认MySQL套接字,注意要与mysql中的设定一致
///
1056 pdo_mysql.default_socket=/data/mysql/mysql.sock
1165 mysqli.default_socket = /data/mysql/mysql.sock
///
systemctl restart php-fpm.service
###浏览器
访问http://172.25.24.1/phpadmin/index.php
新建库westos
新建表linux
字段name(varchar 20),passwd(varchar 20)
user1=111
mysql -p
> select * from westos.linux;
二、主从复制
MySQL Replication在Master端开启binlog,Master把它的二进制日志传递给slaves来达到master-slave数据一致的目的。
1、初始化从库
在server1主机master主库
中将mysql
的数据目录
以及配置文件
复制到server2主机,即slave从库
。
###server1
scp -r /usr/local/mysql/ server2:/usr/local/
scp /etc/my.cnf server2:/etc/
在从库
中拷贝启动脚本,使mysql可全局使用,添加变量,创建用户,数据目录,初始化,然后开启服务,修改密码。
###server2
cd /usr/local/mysql/support-files
cp mysql.server /etc/init.d/mysqld ##拷贝启动脚本
cd
vim .bash_profile ##添加变量
///
PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
///
source .bash_profile
which mysql ##/usr/local/mysql/bin/mysql
useradd -M -d /data/mysql -s /sbin/nologin mysql
mkdir /data/mysql -p ##创建数据目录
chown mysql.mysql /data/mysql
mysqld --initialize --user=mysql ##初始化数据库,此时会有一个初始密码,先记住
/etc/init.d/mysqld start
mysql_secure_installation ##修改密码
2、在Master端开启binlog
修改配置文件,设定启用binlog
和主库id号,重启服务。在数据目录下,会生成数据库的二进制操作日志和二进制日志的索引文件。
###server1
cd /etc/
vim my.cnf ##修改配置
///
[mysqld]
log-bin=mysql-bin ##表示启用binlog,log-bin决定了msyql 的binlog的名字,⽣成的binlog名字为mysql-bin.000001
server_id=1 ##正整数,可以不是递增,但必须为正
///
/etc/init.d/mysqld restart
cd /data/mysql/
ls ---> mysql-bin.000001 mysql-bin.index ##mysql-bin.000001数据库的二进制操作日志,每重启一次会生成新的;mysql-bin.index,二进制日志的索引文件,记录了所有的日志
进入数据库,添加授权用户,并且进行授权。slave
端可以通过该授权用户进入master端的数据库。
mysql -p
> create user 'repl'@'%' identified by 'westos'; ##添加授权用户
> grant replication slave on *.* to 'repl'@'%'; ##授权
在slave
端(server2主机)进行测试,登陆master端主库。
###server2
mysql -h 172.25.24.1 -u repl -p ##此时并没有什么权限
> show databases;
> exit ##退出
在master端主库
查看主库状态,可以看到二进制操作日志的名称和位置。
###server1
> show master status;
在slave
端修改配置文件,设定server-id
为2,重启服务。进入数据库,设定并查看是否设定完成。
###server2
vim /etc/my.cnf
///
[mysqld]
server_id=2
///
/etc/init.d/mysqld restart
mysql -p
> set global server_id=2;
> show variables like 'server_id';
[注意] 主从复制之前,主从主机数据一定要同步,此时因为主从库数据不同步,所以需要将主库数据备份并传给从库。
3、同步主从库
在master
端主库中查看server-id
以及westos库
,退出数据库。查看日志文件,并备份
库到指定文件,将该文件复制
到slave
端,保证以前的数据可以同步
。
###server1
> show variables like 'server_id';
> show databases;
> exit
cd /data/mysql
mysqlbinlog mysql-bin.000001 ##查看日志
mysqldump -p westos > dump.sql ##备份数据,所有的操作过程
scp dump.sql server2:
在slave
端以管理员身份建库,并将备份文件导入库中。进入数据库,显示数据库名称可以看到westos
库,进入westos库并显示库中的所有表,显示表的结构,查询指定表的所有数据,可以看到数据已经同步。
###server2
cd
mysqladmin -p create westos ##以管理员身份建库,因为dump.sql没有建库,所以需要自己建库
mysql -p westos < dump.sql ##备份导入,在salve端复制执行
mysql -pwestos
> show databases; --> westos ##显示数据库名称
> use westos ##进入westos库
> show tables; --> linux ##显示库中的所有表
> desc linux; --> 字段 ##显示表的结构
> select * from linux; ##查询指定表的所有数据
##可以看到数据已经同步
> exit
重启服务,设定slave从库
在master主库
中以repl
用户身份从指定位置
开始复制
指定二进制日志文件。开启slave端,查看状态可以看到IO线程和SQL线程都为开启状态。查看数据库,同步成功。
/etc/init.d/mysqld restart ##重启服务
mysql -p
> change master to master_host='172.25.24.1', master_user='repl', master_password='westos', master_log_file='mysql-bin.000001', master_log_pos=固定位置;
##slave从某台主机的某个日志,某个位置开始同步,此位置与master主机二进制日志文件的位置相同。
> start slave;
> show slave status\G; ---> Slave_IO_Running: Yes Slave_SQL_Running: Yes
> select * from westos.linux;
三、主-从(主)-从复制+GTID
GTID即全局事务ID (global transaction identifier), 其保证为每一个在主上提交的事务在复制集群中可以生成一个唯一的ID。mysql主从结构在一主一从情况下对于GTID来说就没有优势了,而对于2台主以上的结构优势异常明显,可以在数据不丢失的情况下切换新主。
1、在server1和server2开启gtid
在server1主机master
端mysql配置文件中开启gtid
,并重启服务。
###server1
vim /etc/my.cnf
///
gtid_mode=ON
enforce-gtid-consistency=ON
///
/etc/init.d/mysqld restart
在server2主机slave
端mysql配置文件中开启gtid
,并重启服务。停止slave
端,设定以repl用户自动获取master端的事务。开启slave,查看状态,可以看到,IO线程和SQL线程为running状态。
###server2
vim /etc/my.cnf
///
gtid_mode=ON
enforce-gtid-consistency=ON
///
/etc/init.d/mysqld restart
mysql -p
> stop slave;
> change master to master_host='172.25.24.1', master_user='repl', master_password='westos', master_auto_position = 1;
> start slave;
> show slave status\G; ##Slave_IO_Running: Yes Slave_SQL_Running: Yes
此时在master
端插入数据。
###server1
mysql -pwestos
> use westos
> insert into linux values ('user4','444');
> select * from linux;
2、设定server3为server2主机的slave端
在server2
主机slave
端可以查看到master端插入的数据,查看gtid系统表,可以看到已经复制成功的资源id,退出数据库。将mysql
复制至server3
主机(server2主机作为一台master主机,server3为其slave端)。
###server2
> select * from westos.linux;
> use mysql
> select * from gtid_executed; ##gtid系统表
> exit
scp -r /usr/local/mysql/ server3:/usr/local/
在server1
主机,将配置文件复制至server3
主机。
###server1
scp /etc/my.cnf server3:/etc/
scp /etc/init.d/mysqld server3:/etc/init.d/
在server3主机
编辑配置文件,设定server-id
,开启gtid,新建用户和数据目录,添加变量,初始化数据库,开启服务,修改密码。
###server3
vim /etc/my.cnf
///
server-id=3
gtid_mode=ON
enforce-gtid-consistency=ON
///
useradd -M -d /data/mysql -s /sbin/nologin mysql
vim .bash_profile ##添加变量
///
PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
///
source .bash_profile
mkdir /data/mysql -p ##创建数据目录
chown mysql.mysql /data/mysql
mysqld --initialize --user=mysql ##初始化数据库,此时会有一个初始密码,先记住
/etc/init.d/mysqld start
mysql_secure_installation ##修改密码
在server2
主机启用binlog,同时记录日志,重启服务,进入数据库,查看slave状态,建立一个专门用于复制数据的用户。
###server2
vim /etc/my.cnf
///
log-bin=mysql-bin ##启用binlog
server-id=2
log_slave_updates=ON ##作为slave的同时又作为master,则记录日志
gtid_mode=ON
enforce-gtid-consistency=ON
///
/etc/init.d/mysqld restart
mysql -pwestos
> show slave status\G;
> grant replication slave on *.* to repl@'%' identified by 'westos'; ##在主服务器建立一个专门用于复制数据的用户
在server1
备份westos库
,并复制至server3主机。
###server1
mysqldump -p westos > dump.sql ##备份
scp dump.sql server3:
在server3
主机以管理员权限建库,导入westos库
。进入数据库,设定以repl
用户自动获取master端的事务,开启slave端,查看状态。
###server3
mysqladmin -p create westos ##以管理员权限建库
mysql -p westos < dump.sql
mysql -pwestos
> use westos
> show tables;
> select * from linux;
> change master to master_host='172.25.24.1', master_user='repl', master_password='westos', master_auto_position = 1;
> start slave;
> show slave status\G; ##slave_io_running:yes slave_sql_running:yes
在server1
主机插入数据。
###server1
> use westos
> insert into linux values ('user5','555');
在server3
可以查看到server1插入的数据。
四、半同步(对io进行设定)
异步复制:主库只负责发送,从库只负责接受,主库没有确认复制的过程,如果网络延迟或者设备中断,会导致数据不同步。
show processlist
; 可以查看io和sql线程
io延迟:网络延迟
sql延迟:因为主库上多个线程对数据库进行写入,但从库只有一个线程进行回放,不可避免会产生延迟。
当读和写的同步需求很高,异步复制就不能够稳定复制。
AFTER_COMMIT
原理:master将binlog发送给slave端,同时保存本地,进行引擎提交,等待slave端完成操作,返回给master端ack信息,同时返回用户ok信息。
但问题是,进行引擎提交后,salve端没有完成操作,但此时同时登陆的另一个用户已经可以看到提交的信息,如果此时master端挂掉,slave端没有保存信息,而另一用户已经看到的信息也会消失。
AFTER_SYNC(5.7版本后默认使用)
原理:master将binlog发送给slave端,同时保存本地,等待slave端完成操作,返回给master端ack信息,master端才会进行引擎提交,同时返回用户ok信息。
半同步
在server1(master)
和server2(slave)
主机开启mysql,安装其对应的半同步插件。
###server1
/etc/init.d/mysqld start
mysql -p
> install plugin rpl_semi_sync_master soname 'semisync_master.so'; ##安装半同步插件
###server2
/etc/init.d/mysqld start
mysql -pwestos
> show slave status\G;
> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
在server1
主机验证插件安装状态,显示有关服务器插件的信息,启用半同步。
###server1
> select plugin_name, plugin_status
-> from information_schema.plugins
-> where plugin_name like '%semi%'; ##验证插件安装状态
> show plugins; ##显示有关服务器插件的信息
> set global rpl_semi_sync_master_enabled=1; ##启用半同步,在主从复制的基础上设定
在server2
主机同样启用半同步。
###server2
> set global rpl_semi_sync_slave_enabled=1;
回到server1
主机,查看系统变量。rpl_semi_sync_master_enabled
为ON,超时时间默认10s(生产环境下为无穷大,半同步挂掉则切换为异步,所以需要将等待时间设为无穷大),模式为AFTER_SYNC
。
###server1
> show variables like 'rpl%';
在server2
主机查看系统变量与状态,可以看到rpl_semi_sync_slave_enabled
为ON,但是rpl_semi_sync_slave_status
为OFF。
###server2
> show variables like 'rpl%'; ##rpl_semi_sync_slave_enabled为ON
> show status like 'rpl%'; ##rpl_semi_sync_slave_status为OFF
在server1
查看,rpl_semi_sync_master_status
为ON,但是rpl_semi_sync_master_clients
为0,表示没有slave端。
当server2
主机,停止IO线程,然后重新开启,以刷新设定,使rpl_semi_sync_slave_status
为ON。
###server2
> stop slave IO_THREAD;
> start slave IO_THREAD;
> show status like 'rpl%'; ##rpl_semi_sync_slave_status为ON
在server1端查看,此时rpl_semi_sync_master_clients
为1,表示有slave端,插入数据,重新查看,rpl_semi_sync_master_yes_tx
为1,表示同步成功1次。
###server1
> show status like 'rpl%'; ##rpl_semi_sync_master_clients为1,有slave端
> use westos
> show plugins;
> insert into linux values ('user5','555');
> show status like 'rpl%'; ##rpl_semi_sync_master_yes_tx为1,同步成功1次
在server2
查看,可以看到插入的数据,表示同步成功。当关闭IO,则无法同步。
在server1重新插入数据,查看状态,rpl_semi_sync_master_status
为OFF,rpl_semi_sync_master_no_tx
为1,同步失败1次。
###server1
> insert into linux values ('user7','777');
> show status like 'rpl%'; ##rpl_semi_sync_master_status为OFF,rpl_semi_sync_master_no_tx为1,同步失败1次
此时在server2
主机可以看到数据没有同步,然后重新开启IO线程。
###server2
> select * from linux; ##没有user7,同步失败
> start slave IO_THREAD; ##重新开启IO
在server1
主机查看开启IO后的状态,rpl_semi_sync_master_status
为ON,插入数据,查看状态,rpl_semi_sync_master_yes_tx
数目增加1,表示同步成功。
###server1
> show status like 'rpl%'; ##rpl_semi_sync_master_status为ON
> insert into linux values ('user8','888');
> show status like 'rpl%'; ##rpl_semi_sync_master_yes_tx数目增加1,表示同步成功
> show processlist; ##binlog dump GTID 发送成功
在server2
主机查看数据,此时已经全部同步。
###server2
> select * from linux;
> show processlist; ##binlog dump GTID master已经发送到slave