MySQL是C/S 架构的,connectors是连接器;可供Native C API、JDBC、ODBC、NET、PHP、Perl、Python、Ruby、Cobol等连接mysql;ODBC叫开放数据库(系统)互联,open database connection;
JDBC是主要用于java语言利用较为底层的驱动连接数据库;以上这些,站在编程角度可以理解为连入数据库管理系统的驱动,站在mysql角度称作专用语言对应的链接器.
任何链接器连入mysql以后,mysql是单进程多线程模型的,因此,每个用户连接,都会创建一个单独的连接线程;其实mysql连接也有长短连接两种方式,使用mysql客户端连入数据库后,直到使用quit命令才退出,可认为是长连接;使用mysql中的-e选项,在mysql客户端向服务器端申请运行一个命令后则立即退出,也就意味着连接会立即断开;所以,mysql也支持长短连接类似于两种类型;所以,用户连入mysql后,创建一个连接线程,完成之后,能够通过这个链接线程完成接收客户端发来的请求,为其处理请求,构建响应报文并发给客户端;由于是单进程模型,就意味着必须要维持一个线程池,跟
之前介绍过的varnish很接近,需要一个线程池来管理这众多线程是如何对众多客户端的并发请求,完成并发响应的,组件connection pool就是实现这样功能;connection pool对于mysql而言,它所实现的功能,包括authentication认证,用户发来的账号密码是否正确要完成认证功能;thread reuse线程重用功能,一般当一个用户连接进来以后要用一个线程来响应它,而后当用户退出这个线程有可能并非被销毁,而是把它清理完以后,重新收归到线程池当中的空闲线程中去,以完成所谓的线程重用;connection limit 线程池的大小决定了连接并发数量的上限,例如,最多容纳100线程,一旦到达此上限后续到达的连接请求则只能排队或拒绝连接;check memory用来检测内存,caches实现线程缓存;整个都属于线程池的功能.当用户请求之后,通过线程池建立一个用户连接,这个线程一直存在,然后用户就通过这个会话,发送对应的SQL语句到服务器端.
服务器收到SQL语句后,要对语句完成执行,首先要能理解sql语句需要有sql解释器或叫sql接口sql interface就可理解为是整个mysql的外壳,就像shell是linux操作系统的外壳一样道理;用户无论通过哪种链接器发来的基本的SQL请求,当然,事实上通过native C API也有发过来的不是SQL 请求,而仅仅是对API中的传递参数后的调用;不是SQL语句不过都统统理解为sql语句罢了;对SQL而言分为DDL和DML两种类型,但是无论哪种类型,提交以后必须交给内核,让内核来运行,在这之前必须要告诉内核哪个是命令,哪个是选项,哪些是参数,是否存在语法错误等等;因此,这个整个SQL 接口就是一个
完完整整的sql命令的解释器,并且这个sql接口还有提供完整的sql接口应该具备的功能,比如支持所谓过程式编程,支持代码块的实现像存储过程、存储函数,触发器、必要时还要实现部署一个关系型数据库应该具备的基本组件例如视图等等,其实都在sql interface这个接口实现的;SQL接口做完词法分析、句法分析后,要分析语句如何执行让parser解析器或分析器实现,parser是专门的分析器,这个分析器并不是分析语法问题的,语法问题在sql接口时就能发现是否有错误了,一个语句没有问题,就要做执行分析,所谓叫查询翻译,把一个查询语句给它转换成对应的能够在本地执行的特定操作;比如说
看上去是语句而背后可能是执行的一段二进制指令,这个时候就完成对应的指令,还要根据用户请求的对象,比如某一字段查询内容是否有对应数据的访问权限,或叫对象访问权限;在数据库中库、表、字段、字段中的数据有时都称为object,叫一个数据库的对象,用户认证的通过,并不意味着就能一定能访问数据库上的所有数据,所以说,mysql的认证大概分为两过程都要完成,第一是连入时需要认证账号密码是否正确这是authentication,然后,验证成功后用户发来sql语句还要验证用户是否有权限获取它期望请求获取的数据;这个称为object privilege,这一切都是有parser分析器进行的.
分析器分析完成之后,可能会生成多个执行树,也就意味着为了能够达到访问期望访问到的目的,可能有多条路径都可实现,就像文件系统一样可以使用相对路径也可使用绝对路径;它有多种方式,在多种路径当中一定有一个是最优的,类似路由选择,因此,optimizer就要去衡量多个访问路径中哪一个代价或开销是最小的,这个开销的计算要依赖于索引等各种内部组件来进行评估;而且这个评估的只是近似值,同时还要考虑到当前mysql内部在实现资源访问时统计数据,比如,根据判断认为是1号路径的开销最小的,但是众多统计数据表明发往1号路径的访问的资源开销并不小,并且比3号路径大的多,因此,可能会依据3号路径访问;这就是所谓的optimizer它负责检查多条路径,每条路径的开销,然后评估开销,这个评估根据内部的静态数据,索引,根域根据动态生成的统计数据来判定每条路径的开销大小,因此这里还有statics;一旦优化完成之后,还要生成统计数据,这就是优化器的作用;如果没有优化器mysql执行语句是最慢的,其实优化还包括一种功能,一旦选择完一条路径后,例如用户给的这个命令执行起来,大概需要100个开销,如果通过改写语句能够达到同样目的可能只需要30个开销;于是,optimizer还要试图改写sql语句;所以优化本身还包括查询语句的改写;一旦优化完成,接下来就交给存储引擎完成.
mysql是插件式存储引擎,它就能够替换使用选择多种不同的引擎,MyISAM是MySQL 经典的存储引擎之一,InnoDB是innobase提供给MySQL的,NDB主要用于MySQL Cluster 分布式集群环境,archive做归档的等等,还有许多第三方开发的存储引擎;存储引擎负责把具体分析的结果完成对磁盘上文件路径访问的转换,数据库中的行数据都是存储在磁盘块上的,因此存储引擎要把数据库数据映射为磁盘块,并把磁盘块加载至内存中;进程实现数据处理时,是不可能直接访问磁盘上的数据的,因为它没有权限,只有让内核来把它所访问的数据加载至内存中以后,进程在内存中完成修改,由内核再负责把数
据存回磁盘;对于文件系统而言,数据的存储都是以磁盘块方式存储的,但是,mysql在实现数据组织时,不完全依赖于磁盘,而是把磁盘块再次组织成更大一级的逻辑单位,类似于lvm中的PE或LE的形式;其实,MySQL的存储引擎在实现数据管理时,也是在文件系统之上布设文件格式,对于文件而言在逻辑层上还会再次组织成一个逻辑单位,这个逻辑单位称为mysql的数据块datablock 一般为16k ,对于关系型数据库,数据是按行存储的;一般一行数据都是存储在一起的,因此,MySQL 在内部有一个数据块datablock,在datablock就存储一行数据,一个数据块里可能存放了n行数据;将来在查询加载一行数据时,内核会把整个一个数据数据块加载至内存中,而mysql存储引擎,就从中挑出来某一行返回给查询者,是这样实现的;所以整个存储是以datablock在底层为其最终级别的.
事实上,整个存取过程,尤其是访问比较热点的数据,也不可能每一次当用户访问时或当某SQL语句用到时再临时从磁盘加载到内存中,因此,为了能够加上整个性能,mysql的有些存储引擎可以实现,把频繁访问到的热点数据,统统装入内存,用户访问、修改时直接在内存中操作,只不过周期性的写入磁盘上而已,比如像InnoDB,所以caches和buffers组件就是实现此功能的;MySQL为了执行加速,因为它会不断访问数据,而随计算机来说io是最慢的一环,尤其是磁盘io,所以为了加速都载入内存中管理;这就需要MySQL 维护cache和buffer缓存或缓冲;这是由MySQL 服务器自己维护的;有很多存储
引擎自己也有cache和buffer;一个数据库提供了3种视图,物理视图就是看到的对应的文件系统存储为一个个的文件,MySQL的数据文件类型,常见的有redo log重做日志,undo log撤销日志,data是真正的数据文件,index是索引文件,binary log是二进制日志文件,error log错误日志,query log查询日志,slow query log慢查询日志,在复制架构中还存在中继日志文件,跟二进制属于同种格式;这是mysql数据文件类型,也就是物理视图;逻辑视图这是在mysql接口上通过存储引擎把mysql文件尤其是data文件,给它映射为一个个关系型数据库应该具备组成部分,比如表,一张表在底层是一个数据文件而已,里面组织的就是datablock,最终映射为磁盘上文件系统的block,然后再次映射为本地扇区的
存储,但是整个mysql需要把他们映射成一个二维关系表的形式,需要依赖sql接口以及存储引擎共同实现;所以,把底层数据文件映射成关系型数据库的组件就是逻辑视图;DBA 就是关注内部组件是如何运作的,并且定义、配置其运作模式,而链接器都是终端用户通过链接器的模式进入数据库来访问数据;数据集可能非常大,每一类用户可能只有一部分数据的访问权限,这个时候,最终的终端用户所能访问到的数据集合称作用户视图;为了保证MySQL运作还提供了管理和服务工具,例如:备份恢复工具,安全工具,复制工具,集群服务,管理、配置、迁移、元数据等工具。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1LYZqqUv-1576071563153)(C:%5CUsers%5CAdministrator%5CDesktop%5C%E6%88%AA%E5%9B%BE%5C2019%E5%B9%B411%E6%9C%8821%E6%97%A5%5Cimage-20191122205539468.png)]
参看:https://mariadb.com/kb/en/library/xtradbinnodb-server-system-variables/#innodb_file_per_table
show engines;
show variables like '%storage_engine%';
vim /etc/my.conf
[mysqld]
default_storage_engine= InnoDB
show table status from db_name;
show table status like 'tb_name';
show create table tb_name;
CREATE TABLE tb_name(... ) ENGINE=InnoDB;
ALTER TABLE tb_name ENGINE=InnoDB;
是mysql的核心数据库,类似于Sql Server中的master库,主要负责存储数据库的用户、权限设置、关键字等mysql自己需要使用的控制和管理信息
MySQL 5.5开始新增的数据库,主要用于收集数据库服务器性能参数,库里表的存储引擎均为PERFORMANCE_SCHEMA,用户不能创建存储引擎为PERFORMANCE_SCHEMA的表
MySQL 5.0之后产生的,一个虚拟数据库,物理上并不存在information_schema数据库类似与“数据字典”,提供了访问数据库元数据的方式,即数据的数据。比如数据库名或表名,列类型,访问权限(更加细化的访问方式)
https://dev.mysql.com/doc/refman/5.7/en/server-option-variable-reference.html
https://mariadb.com/kb/en/library/full-list-of-mariadb-options-system-and-status-variables/
其中有些参数支持运行时修改,会立即生效;有些参数不支持,且只能通过修改配置文件,并重启服务器程序生效;有些参数作用域是全局的,且不可改变;有些可以为每个用户提供单独(会话)的设置
mysqld --help --verbose
mysqld --print-defaults #获取默认设置
shell> ./mysqld_safe --skip-name-resolve=1
vim /etc/my.cnf
[mysqld]
skip_name_resolve=1
skip-grant-tables
获取系统变量
SHOW GLOBAL VARIABLES;
SHOW [SESSION] VARIABLES;
SHOW VARIABLES LIKE 'VAR_NAME';
SELECT @@VAR_NAME;
修改服务器变量的值:
help SET;
修改全局变量:仅对修改后新创建的会话有效,对已经建立的会话无效
SET GLOBAL system_var_name=value;
SET @@global.system_var_name=value;
修改会话变量:
SET [SESSION] system_var_name=value;
SET @@[session.]system_var_name=value;
MariaDB [hellodb]> set global max_connections=2000;
Query OK, 0 rows affected (0.000 sec)
MariaDB [hellodb]> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 2000 |
+-----------------+-------+
1 row in set (0.001 sec)
SHOW GLOBAL STATUS;
SHOW [SESSION] STATUS;
MariaDB [hellodb]> SHOW GLOBAL STATUS like 'com_select';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select | 5 |
+---------------+-------+
1 row in set (0.001 sec)
参考:
https://mariadb.com/kb/en/library/sql-mode/
https://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_sql-mode
查询执行路径
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hObChPn6-1576071563156)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191122213710692.png)]
查询缓存原理
优缺点
哪些查询可能不会被缓存
查询缓存相关的服务器变量
参考:
https://mariadb.com/kb/en/library/server-system-variables/#query_cache_type
https://dev.mysql.com/doc/refman/5.7/en/query-cache-configuration.html
查询缓存相关的状态变量:
SHOW GLOBAL STATUS LIKE 'Qcache%';
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v9PYityj-1576071563156)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191122214447034.png)]
[root@centos7 ~]#vim /etc/my.cnf
[mysqld]
query_cache_type=ON
query_cache_size=10M
[root@centos8 ~]#systemctl restart mariadb
[root@centos8 ~]#mysql -uroot -p
MariaDB [(none)]> show variables like 'query_cache%';
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 1048576 |
| query_cache_strip_comments | OFF |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------+---------+
6 rows in set (0.001 sec)
MariaDB [(none)]> SHOW GLOBAL STATUS LIKE 'Qcache%';
+-------------------------+---------+
| Variable_name | Value |
+-------------------------+---------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 1027736 |
| Qcache_hits | 3 |
| Qcache_inserts | 3 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 0 |
| Qcache_queries_in_cache | 3 |
| Qcache_total_blocks | 8 |
+-------------------------+---------+
8 rows in set (0.003 sec)
二叉树
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q4wTniAj-1576071563157)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191122214917567.png)]
红黑树
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q7QD4z6w-1576071563158)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191122214956393.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ggFIVq1i-1576071563158)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191122215030147.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ckBC6Fx6-1576071563159)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191122215102077.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yS9O432s-1576071563160)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191122215455987.png)]
独立地使用列:尽量避免其参与运算,独立的列指索引列不能是表达式的一部分,也不能是函数的参数,在where条件中,始终将索引列单独放在比较符号的一侧
左前缀索引:构建指定索引字段的左侧的字符数,要通过索引选择性来评估
多列索引:AND操作时更适合使用多列索引,而非为每个列创建单独的索引
选择合适的索引列顺序:无排序和分组时,将选择性最高放左侧
只要列中含有NULL值,就最好不要在此列设置索引,复合索引如果有NULL值,此列在使用时也不会使用索引
尽量使用短索引,如果可以,应该制定一个前缀长度
对于经常在where子句使用的列,最好设置索引
对于有多个列where或者order by子句,应该建立复合索引
对于like语句,以%或者‘-’开头的不会使用索引,以%结尾会使用索引
尽量不要在列上进行运算(函数操作和表达式操作)
尽量不要使用not in和<>操作
查询时,能不要*就不用*,尽量写全字段名
大部分情况连接效率远大于子查询
多表连接时,尽量小表驱动大表,即小表 join 大表
在有大量记录的表分页时使用limit
对于经常使用的查询,可以开启缓存
多使用explain和profile分析查询语句
查看慢查询日志,找出执行时间长的sql语句优化
创建索引:
CREATE [UNIQUE] INDEX index_name ON tbl_name (index_col_name[(length)],...);
ALTER TABLE tbl_name ADD INDEX index_name(index_col_name);
help CREATE INDEX;
删除索引:
DROP INDEX index_name ON tbl_name;
ALTER TABLE tbl_name DROP INDEX index_name(index_col_name);
查看索引:
SHOW INDEXES FROM [db_name.]tbl_name;
优化表空间:
OPTIMIZE TABLE tb_name;
查看索引的使用
SET GLOBAL userstat=1;
SHOW INDEX_STATISTICS;
EXPLAIN SELECT clause
列名 | 说明 |
---|---|
id | 执行编号,标识select所属的行。如果在语句中没子查询或关联查询,只有唯一 的select,每行都将显示1。否则,内层的select语句一般会顺序编号,对应于 其在原始语句中的位置 |
select_type | 简单查询:SIMPLE| 复杂查询:PRIMARY(最外面的SELECT)、DERIVED(用于FROM中的子查 询)、UNION(UNION语句的第一个之后的SELECT语句)、UNION RESUlT(匿名临时表)、SUBQUERY(简单子查询) |
table | 访问引用哪个表(引用某个查询,如“derived3”) |
type | 关联类型或访问类型,即MySQL决定的如何去查询表中的行的方式 |
possible_keys | 查询可能会用到的索引 |
key | 显示mysql决定采用哪个索引来优化查询 |
key_len | 显示mysql在索引里使用的字节数 |
ref | 根据索引返回表中匹配某单个值的所有行 |
rows | 为了找到所需的行而需要读取的行数,估算值,不精确。通过把所有rows列值 相乘,可粗略估算整个查询会检查的行数 |
Extra | 额外信息 Using index:MySQL将会使用覆盖索引,以避免访问表 Using where:MySQL服务器将在存储引擎检索后,再进行一次过滤 Using temporary:MySQL对结果排序时会使用临时表 Using filesort:对结果使用一个外部索引排序 |
说明: type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:system > const >eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range >index > ALL ,一般来说,得保证查询至少达到range级别,最好能达到ref
类型 | 说明 |
---|---|
All | 最坏的情况,全表扫描 |
index | 和全表扫描一样。只是扫描表的时候按照索引次序进行而不是行。主要优点就是避免 了排序, 但是开销仍然非常大。如在Extra列看到Using index,说明正在使用覆盖索 引,只扫描索引的数据,它比按索引次序全表扫描的开销要小很多 |
range | 范围扫描,一个有限制的索引扫描。key 列显示使用了哪个索引。当使用=、 <>、>、 >=、<、<=、IS NULL、<=>、BETWEEN 或者 IN 操作符,用常量比较关键字列时,可以 使用 range |
ref | 一种索引访问,它返回所有匹配某个单个值的行。此类索引访问只有当使用非唯一性 索引或唯一性索引非唯一性前缀时才会发生。这个类型跟eq_ref不同的是,它用在关 联操作只使用了索引的最左前缀,或者索引不是UNIQUE和PRIMARY KEY。ref可以用 于使用=或<=>操作符的带索引的列。 |
eq_ref | 最多只返回一条符合条件的记录。使用唯一性索引或主键查找时会发生 (高效) |
const | 当确定最多只会有一行匹配的时候,MySQL优化器会在查询前读取它而且只读取一 次,因此非常快。当主键放入where子句时,mysql把这个查询转为一个常量(高效) |
system | 这是const连接类型的一种特例,表仅有一行满足条件。 |
Null | 意味着mysql能在优化阶段分解查询语句,在执行阶段甚至用不到访问表或索引(高效) |
加锁
LOCK TABLES tbl_name [[AS] alias] lock_type [, tbl_name [[AS] alias]
lock_type] ...
lock_type: READ , WRITE
解锁
UNLOCK TABLES
关闭正在打开的表(清除查询缓存),通常在备份前加全局读锁
FLUSH TABLES [tb_name[,...]] [WITH READ LOCK]
查询时加写或读锁
SELECT clause [FOR UPDATE | LOCK IN SHARE MODE]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ghki23tC-1576071563161)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191123101821721.png)]
显式启动事务:
BEGIN
BEGIN WORK
START TRANSACTION
结束事务:
#提交
COMMIT
#回滚;当数据库服务宕机或者停电了,未提交的事务会回滚
ROLLBACK
set autocommit={1|0}
事务支持保存点:
SAVEPOINT identifier
ROLLBACK [WORK] TO [SAVEPOINT] identifier
RELEASE SAVEPOINT identifier
查看事务:
#查看当前的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
#查看当前锁定的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
#查看当前等锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
可读取到未提交数据,产生脏读(处于中间状态的脏数据);另一个事务可以查看到
#设置为READ-UNCOMMITTED
MariaDB [(none)]> select @@tx_isolation;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set (0.000 sec)
#开启新事务
MariaDB [hellodb]> begin;
Query OK, 0 rows affected (0.000 sec)
#查看数据表
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
+-----+---------------+-----+--------+
4 rows in set (0.001 sec)
#修改数据表
MariaDB [hellodb]> update teachers set age=35 where tid=4;
Query OK, 1 row affected (0.001 sec)
Rows matched: 1 Changed: 1 Warnings: 0
#查看数据表,此时事务还未提交
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 35 | F |
+-----+---------------+-----+--------+
4 rows in set (0.000 sec)
#在其他终端查看此数据表,可以看到数据已经修改的中间状态(脏数据)
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 35 | F |
+-----+---------------+-----+--------+
4 rows in set (0.000 sec)
可读取到提交数据,但未提交数据不可读,产生不可重复读(每次读取的数据不一样),即可读取到多个提交数据,导致每次读取数据不一致
#修改事务隔离级别为READ-COMMITTED
MariaDB [hellodb]> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1 row in set (0.000 sec)
#开启新事务
MariaDB [hellodb]> begin;
Query OK, 0 rows affected (0.000 sec)
#修改数据库:插入新纪录
MariaDB [hellodb]> insert teachers (name,age,gender) values('alice',30,'F');
Query OK, 1 row affected (0.001 sec)
#查看数据库,新纪录已经添加
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
| 5 | alice | 30 | F |
+-----+---------------+-----+--------+
5 rows in set (0.001 sec)
#在另一个终端查看此数据库,数据显示未修改
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
+-----+---------------+-----+--------+
4 rows in set (0.001 sec)
#数据提交
MariaDB [hellodb]> commit;
Query OK, 0 rows affected (0.004 sec)
#在另一个终端查看,数据更改;数据隔离性差,每次查看到的数据都不一样
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
| 5 | alice | 30 | F |
+-----+---------------+-----+--------+
5 rows in set (0.001 sec)
可重复读,多次读取数据都一致,产生幻读(被另一个终端删除的数据也能查看到),即读取过程中,即使有其它提交的事务修改数据,仍只能读取到未修改前的旧数据。此为MySQL默认设置!
#默认的事务隔离级别是REPEATABLE-READ
MariaDB [hellodb]> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.001 sec)
#两个终端都开启事务
MariaDB [hellodb]> begin;
Query OK, 0 rows affected (0.000 sec)
MariaDB [hellodb]> begin;
Query OK, 0 rows affected (0.000 sec)
#查看数据表
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
| 5 | alice | 30 | F |
| 6 | tom | 35 | M |
| 7 | jack | 44 | M |
+-----+---------------+-----+--------+
7 rows in set (0.001 sec)
#添加新数据
MariaDB [hellodb]> insert teachers (name,age,gender) values('james',34,'M');
Query OK, 1 row affected (0.000 sec)
#修改数据的终端可以查看到新记录已经修改
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
| 5 | alice | 30 | F |
| 6 | tom | 35 | M |
| 7 | jack | 44 | M |
| 8 | james | 34 | M |
+-----+---------------+-----+--------+
8 rows in set (0.000 sec)
#另一个终端查看不到已修改的数据【自己修改自己的,互不影响,但是会导致幻读,看到假的数据),好处是隔离性比较好】
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
| 5 | alice | 30 | F |
| 6 | tom | 35 | M |
| 7 | jack | 44 | M |
+-----+---------------+-----+--------+
7 rows in set (0.000 sec)
#两个终端都提交事务时
MariaDB [hellodb]> commit;
Query OK, 0 rows affected (0.001 sec)
MariaDB [hellodb]> commit;
Query OK, 0 rows affected (0.000 sec)
#在另一个终端可以查看到新修改后的数据
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
| 5 | alice | 30 | F |
| 6 | tom | 35 | M |
| 7 | jack | 44 | M |
| 8 | james | 34 | M |
+-----+---------------+-----+--------+
8 rows in set (0.001 sec)
#删除的数据,在另一个终端可以查看到;修改删除的数据不会显示报错,会显示修改数为0。
MariaDB [hellodb]> update teachers set age=55 where tid=8;
Query OK, 0 rows affected (0.000 sec)
Rows matched: 0 Changed: 0 Warnings: 0
可串行化,未提交的读事务阻塞修改事务(加读锁,不阻塞读事务),或者未提交的修改事务阻塞读事务(加写锁,其他事务读写都不可以执行)。会导致并发性能差(数据安全)
#设置事务隔离级别为SERIALIZABLE
MariaDB [hellodb]> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE |
+----------------+
1 row in set (0.000 sec)
#两终端都开启事务
#查看数据表都没有问题
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
| 5 | alice | 30 | F |
| 6 | tom | 35 | M |
| 7 | jack | 44 | M |
+-----+---------------+-----+--------+
7 rows in set (0.001 sec)
#但是修改不了(因为开启事务后,查看数据表,加了读锁【共享锁】,另一个终端只能查看,不能修改数据)
#未提交的读事务阻塞修改事务
#超时后,报错
MariaDB [hellodb]> update teachers set age=55 where tid=7;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
#当一个事务提交之后,在超时时间内,修改会立即生效
MariaDB [hellodb]> commit;
Query OK, 0 rows affected (0.000 sec)
MariaDB [hellodb]> update teachers set age=55 where tid=7;
Query OK, 1 row affected (41.561 sec) #时间41.6s
Rows matched: 1 Changed: 1 Warnings: 0
**************************************************************************************
#重新开启事务:测试未提交的修改事务阻塞读事务
MariaDB [hellodb]> begin;
Query OK, 0 rows affected (0.000 sec)
#修改数据
MariaDB [hellodb]> update teachers set age=55 where tid=7;
Query OK, 1 row affected (0.001 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
| 5 | alice | 30 | F |
| 6 | tom | 35 | M |
| 7 | jack | 55 | M |
+-----+---------------+-----+--------+
7 rows in set (0.001 sec)
MariaDB [hellodb]> begin;
Query OK, 0 rows affected (0.000 sec)
#另一个终端无法查看修改数据(加写锁)
MariaDB [hellodb]> select * from teachers;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
#事务提交后
MariaDB [hellodb]> commit;
Query OK, 0 rows affected (0.002 sec)
#可以查看数据了
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
| 5 | alice | 30 | F |
| 6 | tom | 35 | M |
| 7 | jack | 55 | M |
+-----+---------------+-----+--------+
7 rows in set (7.840 sec)
##超时时间:执行命令后没反应后,多长时间后报错。
MariaDB [hellodb]> show variablequits like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 50 |
+--------------------------+-------+
1 row in set (0.002 sec)
MVCC和事务的隔离级别:
#默认选项(10.3.11-MariaDB)企业环境常用隔离级别REPEATABLE-READ
MariaDB [hellodb]> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.000 sec)
SET tx_isolation=''
READ-UNCOMMITTED
READ-COMMITTED
REPEATABLE-READ
SERIALIZABLE
配置文件选项是 transaction-isolation 与服务器变量不同
vim /etc/my.cnf
[mysqld]
transaction-isolation=SERIALIZABLE
两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态(系统自动发现后自动牺牲一个代价小的事务,使数据回滚,使另一方执行)
#两个终端同时开启事务
#终端2
MariaDB [hellodb]> begin;
Query OK, 0 rows affected (0.000 sec)
#2终端修改数据tid=1
MariaDB [hellodb]> update teachers set age=120 where tid=1;
Query OK, 1 row affected (0.001 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 120 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 55 | F |
| 5 | alice | 55 | F |
| 6 | tom | 55 | M |
| 7 | jack | 55 | M |
+-----+---------------+-----+--------+
7 rows in set (0.000 sec)
#2终端修改数据tid=2
MariaDB [hellodb]> update teachers set age=55 where tid=2;
Query OK, 1 row affected (16.865 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 120 | M |
| 2 | Zhang Sanfeng | 55 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 55 | F |
| 5 | alice | 55 | F |
| 6 | tom | 55 | M |
| 7 | jack | 55 | M |
+-----+---------------+-----+--------+
7 rows in set (0.001 sec)
#终端1
MariaDB [hellodb]> begin;
Query OK, 0 rows affected (0.000 sec)
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 55 | F |
| 5 | alice | 55 | F |
| 6 | tom | 55 | M |
| 7 | jack | 55 | M |
+-----+---------------+-----+--------+
7 rows in set (0.001 sec)
#1终端修改数据tid=2
MariaDB [hellodb]> update teachers set age=55 where tid=2;
Query OK, 1 row affected (0.001 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 55 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 55 | F |
| 5 | alice | 55 | F |
| 6 | tom | 55 | M |
| 7 | jack | 55 | M |
+-----+---------------+-----+--------+
7 rows in set (0.001 sec)
#1终端修改数据tid=1(形成死锁,数据回滚,还原成修改前的数据)
MariaDB [hellodb]> update teachers set age=120 where tid=1;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 55 | F |
| 5 | alice | 55 | F |
| 6 | tom | 55 | M |
| 7 | jack | 55 | M |
+-----+---------------+-----+--------+
7 rows in set (0.001 sec)
SELECT * FROM information_schema.INNODB_TRX;
#trx_mysql_thread_id:事务ID(一个事务11未结束,影响另一个事务12的进行)
# 查看正在进行的事务
MariaDB [hellodb]> SELECT * FROM information_schema.INNODB_TRX\G;
*************************** 1. row ***************************
trx_id: 224
trx_state: LOCK WAIT
trx_started: 2019-11-26 11:52:46
trx_requested_lock_id: 224:11:3:3
trx_wait_started: 2019-11-26 11:57:33
trx_weight: 2
trx_mysql_thread_id: 12
trx_query: update teachers set age=55 where tid=2
trx_operation_state: starting index read
trx_tables_in_use: 1
trx_tables_locked: 1
trx_lock_structs: 2
trx_lock_memory_bytes: 1136
trx_rows_locked: 2
trx_rows_modified: 0
trx_concurrency_tickets: 0
trx_isolation_level: REPEATABLE READ
trx_unique_checks: 1
trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
trx_is_read_only: 0
trx_autocommit_non_locking: 0
*************************** 2. row ***************************
trx_id: 221
trx_state: RUNNING
trx_started: 2019-11-26 11:51:46
trx_requested_lock_id: NULL
trx_wait_started: NULL
trx_weight: 5
trx_mysql_thread_id: 11
trx_query: NULL
trx_operation_state: NULL
trx_tables_in_use: 0
trx_tables_locked: 1
trx_lock_structs: 3
trx_lock_memory_bytes: 1136
trx_rows_locked: 2
trx_rows_modified: 2
trx_concurrency_tickets: 0
trx_isolation_level: REPEATABLE READ
trx_unique_checks: 1
trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
trx_is_read_only: 0
trx_autocommit_non_locking: 0
2 rows in set (0.001 sec)
#查看进程11|12;因为是死锁,11进程影响12进程的操作,可以kill 11进程(强行关闭),使12进程继续进行
MariaDB [hellodb]> show processlist;
+----+-------------+-----------+---------+---------+------+--------------------------+----------------------------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+----+-------------+-----------+---------+---------+------+--------------------------+----------------------------------------+----------+
| 1 | system user | | NULL | Daemon | NULL | InnoDB purge coordinator | NULL | 0.000 |
| 3 | system user | | NULL | Daemon | NULL | InnoDB purge worker | NULL | 0.000 |
| 2 | system user | | NULL | Daemon | NULL | InnoDB purge worker | NULL | 0.000 |
| 4 | system user | | NULL | Daemon | NULL | InnoDB purge worker | NULL | 0.000 |
| 5 | system user | | NULL | Daemon | NULL | InnoDB shutdown handler | NULL | 0.000 |
| 11 | root | localhost | hellodb | Sleep | 70 | | NULL | 0.000 |
| 12 | root | localhost | hellodb | Query | 35 | Updating | update teachers set age=55 where tid=2 | 0.000 |
| 13 | root | localhost | hellodb | Query | 0 | Init | show processlist | 0.000 |
+----+-------------+-----------+---------+---------+------+--------------------------+----------------------------------------+----------+
8 rows in set (0.000 sec)
#查看锁定的事务;11进程被锁定
MariaDB [hellodb]> SELECT * FROM information_schema.INNODB_LOCKS\G;
*************************** 1. row ***************************
lock_id: 224:11:3:3
lock_trx_id: 224
lock_mode: X
lock_type: RECORD
lock_table: `hellodb`.`teachers`
lock_index: PRIMARY
lock_space: 11
lock_page: 3
lock_rec: 3
lock_data: 2
*************************** 2. row ***************************
lock_id: 221:11:3:3
lock_trx_id: 221
lock_mode: X
lock_type: RECORD
lock_table: `hellodb`.`teachers`
lock_index: PRIMARY
lock_space: 11
lock_page: 3
lock_rec: 3
lock_data: 2
2 rows in set (0.001 sec)
ERROR: No query specified
#强制结束进程11
MariaDB [hellodb]> KILL 11;
Query OK, 0 rows affected (0.000 sec)
#查看被锁定的事务,显示无
MariaDB [hellodb]> SELECT * FROM information_schema.INNODB_LOCKS\G;
Empty set (0.001 sec)
ERROR: No query specified
#修改锁定的数据正常(进程12)
MariaDB [hellodb]> update teachers set age=55 where tid=2;
Query OK, 1 row affected (38.144 sec)
Rows matched: 1 Changed: 1 Warnings: 0
[root@centos8 ~]#ll /var/lib/mysql/ -th
total 121M
-rw-rw---- 1 mysql mysql 48M Nov 25 09:51 ib_logfile0 //事务日志
-rw-rw---- 1 mysql mysql 12M Nov 25 09:51 ibdata1 //事务日志
drwx------ 2 mysql mysql 272 Nov 25 09:50 hellodb
srwxrwxrwx 1 mysql mysql 0 Nov 25 09:22 mysql.sock
-rw-rw---- 1 mysql mysql 24K Nov 25 09:22 tc.log
-rw-rw---- 1 mysql mysql 12M Nov 25 09:22 ibtmp1
-rw-rw---- 1 mysql mysql 992 Nov 20 21:48 ib_buffer_pool
-rw-rw---- 1 mysql mysql 16K Nov 20 21:48 aria_log.00000001
-rw-rw---- 1 mysql mysql 52 Nov 20 21:48 aria_log_control
drwx------ 2 mysql mysql 58 Nov 20 21:36 db_yanyi
-rw-rw---- 1 mysql mysql 0 Nov 19 12:08 multi-master.info
-rw-rw---- 1 mysql mysql 16 Nov 19 12:08 mysql_upgrade_info
drwx------ 2 mysql mysql 20 Nov 19 12:08 performance_schema
drwx------ 2 mysql mysql 4.0K Nov 19 12:08 mysql
-rw-rw---- 1 mysql mysql 48M Nov 19 12:07 ib_logfile1 //事务日志
事务日志:transaction log
错误日志error log
通用日志general log
慢查询日志 slow query log
二进制日志 binary log
中继日志reley log,在主从复制架构中,从服务器用于保存从主服务器的二进制日志中读取的事件
show variables like '%innodb_log%';
innodb_log_file_size 5242880 //每个日志文件大小,处理大事务,将文件调大
innodb_log_files_in_group 2 //日志组成员个数,处理大事务,多设置自几个日志组成员
innodb_log_group_home_dir ./ //事务文件路径,最好是独立的分区,配置文件可以指定路径
innodb_flush_log_at_trx_commit //默认为1
MariaDB [hellodb]> show variables like '%innodb_log%';
+-----------------------------+----------+
| Variable_name | Value |
+-----------------------------+----------+
| innodb_log_buffer_size | 16777216 |
| innodb_log_checksums | ON |
| innodb_log_compressed_pages | ON |
| innodb_log_file_size | 50331648 |
| innodb_log_files_in_group | 2 |
| innodb_log_group_home_dir | ./ |
| innodb_log_optimize_ddl | ON |
| innodb_log_write_ahead_size | 8192 |
+-----------------------------+----------+
8 rows in set (0.002 sec)
innodb_flush_log_at_trx_commit=0|1|2|3 #默认是1;为了保证高性能,最好设为0|2;
MariaDB [hellodb]> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1 |
+--------------------------------+-------+
1 row in set (0.003 sec)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-65YRv47H-1576071563162)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191123104448874.png)]
缓存池 日志缓存 操作系统内存 磁盘数据库文件
1 默认情况下,日志缓冲区将写入日志文件,并在每次事务后执行刷新到磁盘(1s可能有多个事务执行,性能差)。 这是完全遵守ACID特性
0 提交时没有写磁盘的操作; 而是每秒执行一次将日志缓冲区的提交的事务写入刷新到磁盘。 这样可提供更好的性能(速度快),但服务器崩溃可能丢失最后一秒的事务
2 每次提交后都会写入OS的缓冲区,但每秒才会进行一次刷新到磁盘文件中。 性能比0略差一些,但操作系统或停电可能导致最后一秒的交易丢失
3 模拟MariaDB 5.5组提交(每组提交3个同步),此项MariaDB 10.0支持
错误日志
错误日志文件路径
SHOW GLOBAL VARIABLES LIKE 'log_error';
MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'log_error';
+---------------+------------------------------+
| Variable_name | Value |
+---------------+------------------------------+
| log_error | /var/log/mariadb/mariadb.log |
+---------------+------------------------------+
1 row in set (0.002 sec)
##错误文件路径
log_error=/PATH/TO/LOG_ERROR_FILE
是否记录警告信息至错误日志文件
##默认值1
log_warnings=0|1|2|3|4|9(级别不同,记录的信息项不同)
#10.3.11版本默认值是2(centos8自带版本)
MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'log_warnings';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_warnings | 2 |
+---------------+-------+
1 row in set (0.002 sec)
general_log=ON|OFF
#查看通用日志的默认值
MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'general_log%';
+------------------+-------------+
| Variable_name | Value |
+------------------+-------------+
| general_log | OFF(关闭 |
| general_log_file | centos8.log | #存放的文件名称
+------------------+-------------+
2 rows in set (0.001 sec)
MariaDB [hellodb]> set GLOBAL general_log=ON;
Query OK, 0 rows affected (0.004 sec)
MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'general_log%';
+------------------+-------------+
| Variable_name | Value |
+------------------+-------------+
| general_log | ON |
| general_log_file | centos8.log |
+------------------+-------------+
2 rows in set (0.002 sec)
[root@centos8 ~]#ll /var/lib/mysql/ -t
total 188484
-rw-rw---- 1 mysql mysql 1056 Nov 26 14:54 centos8.log
*****************************************************************************************
#通用日志文件修改名称
general_log_file=HOSTNAME.log
MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'general_log_file';
+------------------+-------------+
| Variable_name | Value |
+------------------+-------------+
| general_log_file | centos8.log |
+------------------+-------------+
1 row in set (0.002 sec)
MariaDB [hellodb]> set global general_log_file="general.log";
Query OK, 0 rows affected (0.001 sec)
[root@centos8 ~]#ll /var/lib/mysql/ -t
total 188488
-rw-rw---- 1 mysql mysql 1196 Nov 26 14:56 centos8.log
-rw-rw---- 1 mysql mysql 163 Nov 26 14:56 general.log
*****************************************************************************************
#将通用日志以什么样式(文件或者表或者无)保存
log_output=TABLE|FILE|NONE
MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output | FILE |
+---------------+-------+
1 row in set (0.001 sec)
#修改通用日志,记录通用日志至mysql.general_log表中
MariaDB [mysql]> set global log_output="table";
MariaDB [mysql]> SHOW GLOBAL VARIABLES LIKE 'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output | TABLE |
+---------------+-------+
1 row in set (0.002 sec)
#查看通用日志
MariaDB [mysql]> select * from mysql.general_log\G;
*************************** 1. row ***************************
event_time: 2019-11-26 15:00:54.699867
user_host: root[root] @ localhost []
thread_id: 8
server_id: 1
command_type: Query
argument: SHOW GLOBAL VARIABLES LIKE 'log_output'
*************************** 2. row ***************************
event_time: 2019-11-26 15:01:18.755432
user_host: root[root] @ localhost []
thread_id: 8
server_id: 1
command_type: Query
argument: select * from general_log
slow_query_log=ON|OFF #开启或关闭慢查询
MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'slow_query_log';
+----------------+-------+
| Variable_name | Value |
+----------------+-------+
| slow_query_log | OFF |
+----------------+-------+
1 row in set (0.005 sec)
*****************************************************************************************
long_query_time=N #慢查询的阀值,单位秒
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'long_query_time';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.004 sec)
#生产中要设置小一些的数值(商业网站)
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'long_query_time';
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| long_query_time | 2.000000 |
+-----------------+----------+
1 row in set (0.004 sec)
*****************************************************************************************
slow_query_log_file=HOSTNAME-slow.log #慢查询日志文件
MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'slow_query_log_file';
+---------------------+------------------+
| Variable_name | Value |
+---------------------+------------------+
| slow_query_log_file | centos8-slow.log |
+---------------------+------------------+
1 row in set (0.005 sec)
[root@centos8 ~]#ll /var/lib/mysql/ -t
total 188492
srwxrwxrwx 1 mysql mysql 0 Nov 26 15:19 mysql.sock
-rw-rw---- 1 mysql mysql 164 Nov 26 15:19 centos8-slow.log
#当执行的语句时间超过阈值,则记录到日志
MariaDB [hellodb]> select sleep(1) from teachers;
+----------+
| sleep(1) |
+----------+
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
+----------+
7 rows in set (7.008 sec)
#跟踪查看慢查询日志
[root@centos8 ~]#tail -f /var/lib/mysql/centos8-slow.log
# Time: 191126 15:27:32
# User@Host: root[root] @ localhost []
# Thread_id: 8 Schema: hellodb QC_hit: No
# Query_time: 7.007671 Lock_time: 0.000213 Rows_sent: 7 Rows_examined: 7
# Rows_affected: 0 Bytes_sent: 99
SET timestamp=1574753252;
select sleep(1) from teachers;
#时间较长的原因(是否有效利用索引)
MariaDB [hellodb]> explain select sleep(1) from teachers;
+------+-------------+----------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | teachers | index | NULL | PRIMARY | 2 | NULL | 8 | Using index |
+------+-------------+----------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.001 sec)
*****************************************************************************************
#查询类型且查询时长超过long_query_time,则记录日志
log_slow_filter = admin,filesort,filesort_on_disk,full_join,full_scan,
query_cache,query_cache_miss,tmp_table,tmp_table_on_disk
*****************************************************************************************
#不使用索引或使用全索引扫描的语句,不论是否达到慢查询阀值都记录日志,默认OFF,即不记录
#工作中启用此项功能
log_queries_not_using_indexes=ON
MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'log_queries_not_using_indexes';
+------------.-------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| log_queries_not_using_indexes | OFF |
+-------------------------------+-------+
1 row in set (0.002 sec)
MariaDB [hellodb]> set log_queries_not_using_indexes=ON;
Query OK, 0 rows affected (0.000 sec)
#仅设置自己所在的终端开启此功能;要想所有终端开启此功能,可以使用global来定义此变量
MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'log_queries_not_using_indexes';
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| log_queries_not_using_indexes | OFF |
+-------------------------------+-------+
1 row in set (0.002 sec)
#global级变量修改后,其他终端需要退出后重新进入会话才能生效。
MariaDB [hellodb]> SET GLOBAL log_queries_not_using_indexes=ON;
Query OK, 0 rows affected (0.001 sec)
MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'log_queries_not_using_indexes';
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| log_queries_not_using_indexes | ON |
+-------------------------------+-------+
1 row in set (0.005 sec)
*****************************************************************************************
log_slow_rate_limit = 1 #多少次慢查询才记录,mariadb特有
log_slow_verbosity= Query_plan,explain #记录内容
log_slow_queries = OFF 同slow_query_log #新版已废弃
#查看默认选项是OFF
MariaDB [hellodb]> SHOW VARIABLES LIKE 'profiling';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| profiling | OFF |
+---------------+-------+
1 row in set (0.002 sec)
#打开后,会显示语句执行详细的过程
set profiling = ON
#查看语句,注意结果中的query_id值
show profiles ;
MariaDB [hellodb]> select sleep(1) from teachers;
+----------+
| sleep(1) |
+----------+
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
+----------+
7 rows in set (7.008 sec)
MariaDB [hellodb]> ssss;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'ssss' at line 1
MariaDB [hellodb]> ssss;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'ssss' at line 1
MariaDB [hellodb]> show profiles;
+----------+------------+---------------------------------+
| Query_ID | Duration | Query |
+----------+------------+---------------------------------+
| 1 | 0.00170528 | SHOW VARIABLES LIKE 'profiling' |
| 2 | 7.00723255 | select sleep(1) from teachers |
| 3 | 7.00823484 | select sleep(1) from teachers |
| 4 | 0.00010378 | ssss |
| 5 | 0.00011393 | ssss |
+----------+------------+---------------------------------+
5 rows in set (0.000 sec)
#显示语句的详细执行步骤和时长
Show profile for query #
MariaDB [hellodb]> show profile for query 2;
+------------------------+----------+
| Status | Duration |
+------------------------+----------+
| Starting | 0.000097 |
| Checking permissions | 0.000009 |
| Opening tables | 0.000029 |
| After opening tables | 0.000008 |
| System lock | 0.000005 |
| Table lock | 0.000009 |
| Init | 0.000027 |
| Optimizing | 0.000014 |
| Statistics | 0.000020 |
| Preparing | 0.000030 |
| Executing | 0.000004 |
| Sending data | 0.000045 |
| User sleep | 1.000285 |
| User sleep | 1.001106 |
| User sleep | 1.001061 |
| User sleep | 1.001006 |
| User sleep | 1.001179 |
| User sleep | 1.001126 |
| User sleep | 1.000924 |
| End of update loop | 0.000031 |
| Query end | 0.000005 |
| Commit | 0.000008 |
| Closing tables | 0.000006 |
| Unlocking tables | 0.000005 |
| Closing tables | 0.000008 |
| Starting cleanup | 0.000004 |
| Freeing items | 0.000008 |
| Updating status | 0.000054 |
| Logging slow query | 0.000110 |
| Reset for next command | 0.000009 |
+------------------------+----------+
30 rows in set (0.001 sec)
#显示cpu使用情况
Show profile cpu for query #
show variables like 'binlog_format';
#10.2.4及以上版本默认值是混合型;MariaDB10.2.3版本及以下是语句记录。
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | MIXED |
+---------------+-------+
1 row in set (0.002 sec)
#是否记录二进制日志,默认ON(会话级变量;还原数据库时可以临时禁用二进制日志)
sql_log_bin=ON|OFF
MariaDB [(none)]> select @@sql_log_bin;
+---------------+
| @@sql_log_bin |
+---------------+
| 1 |
+---------------+
1 row in set (0.001 sec)
#指定文件位置(二进制日志文件的路径;最好放在单独的分区,日志很重要);默认OFF,表示不启用二进制日志功能,两项都开启才能记录二进制日志
#只读变量,只能在配置文件中指定文件路径;默认重启mysql服务就会生成新的二进制日志文件(或者达到了文件阈值)
log_bin=/PATH/BIN_LOG_FILE:
MariaDB [(none)]> select @@log_bin;
+-----------+
| @@log_bin |
+-----------+
| 0 |
+-----------+
1 row in set (0.001 sec)
#设置的是文件名以什么开头;不写默认前缀就是'mariadb-bin'
vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
log_bin
log_bin=/data/mysql/logbin/mysql-bin
[root@centos8 ~]#ll /var/lib/mysql/ -th
-rw-rw---- 1 mysql mysql 330 Nov 26 16:10 mariadb-bin.000001
-rw-rw---- 1 mysql mysql 21 Nov 26 16:10 mariadb-bin.index #二进制文件的索引
#二进制日志记录的格式,工作中最好设置为ROW(可以在配置文件修改)
binlog_format=STATEMENT|ROW|MIXED
#单个二进制日志文件的最大体积,到达最大值会自动滚动,默认为1G
#说明:文件达到上限时的大小未必为指定的精确值
max_binlog_size=1073741824
#设定是否启动二进制日志即时同步磁盘功能,默认0,由操作系统决定同步日志到磁盘(性能较好);设置为1,导致磁盘IO大幅增加,降低性能。
sync_binlog=1|0
MariaDB [hellodb]> select @@sync_binlog;
+---------------+
| @@sync_binlog |
+---------------+
| 0 |
+---------------+
1 row in set (0.001 sec)
#二进制日志可以自动删除的天数。 默认为0,即不自动删除
expire_logs_days=N:
MariaDB [hellodb]> select @@expire_logs_days;
+--------------------+
| @@expire_logs_days |
+--------------------+
| 0 |
+--------------------+
1 row in set (0.000 sec)
#执行脚本生成数据库记录
MariaDB [hellodb]> call sp_testlog;
Query OK, 100000 rows affected (48.278 sec)
#数据文件生成
[root@centos8 ~]#ll /var/lib/mysql/hellodb/testlog.* -h
-rw-rw---- 1 mysql mysql 999 Nov 26 12:14 /var/lib/mysql/hellodb/testlog.frm
-rw-rw---- 1 mysql mysql 12M Nov 26 16:31 /var/lib/mysql/hellodb/testlog.ibd
#二进制日志文件追加记录
[root@centos8 logbin]#ll -h
total 33M
-rw-rw---- 1 mysql mysql 29M Nov 26 16:30 mysql-bin.000003
#删除数据记录
MariaDB [hellodb]> delete from testlog;
Query OK, 100000 rows affected (0.429 sec)
#数据文件大小没有变
[root@centos8 ~]#ll /var/lib/mysql/hellodb/testlog.* -h
-rw-rw---- 1 mysql mysql 999 Nov 26 12:14 /var/lib/mysql/hellodb/testlog.frm
-rw-rw---- 1 mysql mysql 12M Nov 26 16:31 /var/lib/mysql/hellodb/testlog.ibd
#二进制日志文件继续追加记录
[root@centos8 logbin]#ll -h
total 33M
-rw-rw---- 1 mysql mysql 31M Nov 26 16:31 mysql-bin.000003
#而继续给此数据表添加记录,他也不会变大(直到数据填满后在变大),二进制日志文件继续追加记录
MariaDB [hellodb]> call sp_testlog;
Query OK, 100000 rows affected (48.320 sec)
[root@centos8 ~]#ll /var/lib/mysql/hellodb/testlog.* -h
-rw-rw---- 1 mysql mysql 999 Nov 26 12:14 /var/lib/mysql/hellodb/testlog.frm
-rw-rw---- 1 mysql mysql 12M Nov 26 16:38 /var/lib/mysql/hellodb/testlog.ibd
#truncate table table_name:清除数据表记录,同时释放数据文件,二进制日志文件继续增加记录
MariaDB [hellodb]> truncate table testlog;
Query OK, 0 rows affected (0.015 sec)
[root@centos8 ~]#ll /var/lib/mysql/hellodb/testlog.* -h
-rw-rw---- 1 mysql mysql 999 Nov 26 12:14 /var/lib/mysql/hellodb/testlog.frm
-rw-rw---- 1 mysql mysql 96K Nov 26 16:39 /var/lib/mysql/hellodb/testlog.ibd
*****************************************************************************************
MariaDB [hellodb]> call sp_testlog;
Query OK, 100000 rows affected (5.533 sec)
[root@centos8 ~]#ll /var/lib/mysql/hellodb/testlog.* -h
-rw-rw---- 1 mysql mysql 999 Nov 26 12:14 /var/lib/mysql/hellodb/testlog.frm
-rw-rw---- 1 mysql mysql 12M Nov 26 16:42 /var/lib/mysql/hellodb/testlog.ibd
MariaDB [hellodb]> delete from testlog;
Query OK, 100000 rows affected (0.413 sec)
[root@centos8 ~]#ll /var/lib/mysql/hellodb/testlog.* -h
-rw-rw---- 1 mysql mysql 999 Nov 26 12:14 /var/lib/mysql/hellodb/testlog.frm
-rw-rw---- 1 mysql mysql 12M Nov 26 16:43 /var/lib/mysql/hellodb/testlog.ibd
#当使用delete命令删除数据记录时,释放数据文件大小,可以使用以下命令(当空间不够时使用)
MariaDB [hellodb]> optimize table testlog;
+-----------------+----------+----------+-------------------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+-----------------+----------+----------+-------------------------------------------------------------------+
| hellodb.testlog | optimize | note | Table does not support optimize, doing recreate + analyze instead |
| hellodb.testlog | optimize | status | OK |
+-----------------+----------+----------+-------------------------------------------------------------------+
2 rows in set (0.199 sec)
[root@centos8 ~]#ll /var/lib/mysql/hellodb/testlog.* -h
-rw-rw---- 1 mysql mysql 999 Nov 26 16:44 /var/lib/mysql/hellodb/testlog.frm
-rw-rw---- 1 mysql mysql 96K Nov 26 16:44 /var/lib/mysql/hellodb/testlog.ibd
SHOW {BINARY | MASTER} LOGS;
MariaDB [hellodb]> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 876 |
| mysql-bin.000002 | 544 |
| mysql-bin.000003 | 87594680 |
| mysql-bin.000004 | 365 |
| mysql-bin.000005 | 76500470 |
+------------------+-----------+
5 rows in set (0.000 sec)
SHOW MASTER STATUS;
MariaDB [hellodb]> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000005 | 76500470 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.000 sec)
Binlog_Do_DB:白名单
Binlog_Ignore_DB:黑名单|某些数据库的二进制日志不记录
#pos文件大小,查看此大小之后的事务
SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]
MariaDB [hellodb]> show binlog events in 'mysql-bin.000002';
+------------------+-----+-------------------+-----------+-------------+-----------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------------+-----------+-------------+-----------------------------------------------------+
| mysql-bin.000002 | 4 | Format_desc | 1 | 256 | Server ver: 10.3.11-MariaDB-log, Binlog ver: 4 |
| mysql-bin.000002 | 256 | Gtid_list | 1 | 299 | [0-1-3] |
| mysql-bin.000002 | 299 | Binlog_checkpoint | 1 | 342 | mysql-bin.000002 |
| mysql-bin.000002 | 342 | Gtid | 1 | 384 | BEGIN GTID 0-1-4 |
| mysql-bin.000002 | 384 | Query | 1 | 490 | use `hellodb`; delete from testlog where id>=600000 |
| mysql-bin.000002 | 490 | Xid | 1 | 521 | COMMIT /* xid=15 */ |
| mysql-bin.000002 | 521 | Stop | 1 | 544 | |
+------------------+-----+-------------------+-----------+-------------+-----------------------------------------------------+
7 rows in set (0.000 sec)
show binlog events in 'mysql-bin.000001' from 6516 limit 2,3
MariaDB [hellodb]> show binlog events in 'mysql-bin.000002' from 299 limit 1,3;
+------------------+-----+------------+-----------+-------------+-----------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+------------+-----------+-------------+-----------------------------------------------------+
| mysql-bin.000002 | 342 | Gtid | 1 | 384 | BEGIN GTID 0-1-4 |
| mysql-bin.000002 | 384 | Query | 1 | 490 | use `hellodb`; delete from testlog where id>=600000 |
| mysql-bin.000002 | 490 | Xid | 1 | 521 | COMMIT /* xid=15 */ |
+------------------+-----+------------+-----------+-------------+-----------------------------------------------------+
3 rows in set (0.001 sec)
mysqlbinlog:二进制日志的客户端命令工具
命令格式:
mysqlbinlog [OPTIONS] log_file…
--start-position= #指定开始位置
--stop-position= #指定结束位置
--start-datetime= #时间格式:YYYY-MM-DD hh:mm:ss
--stop-datetime=
--base64-output[=name] #加密显示 ROW模式记录日志
-v -vvv #详细显示 ROW模式记录日志(row模式记录二进制日志,可以防止误删除操作,更加安全,但是日志文件很大)
mysqlbinlog --start-position=678 --stop-position=752 /var/lib/mysql/mariadbbin.000003 -v
mysqlbinlog --start-datetime="2018-01-30 20:30:10" --stop-datetime="2018-01-
30 20:35:22" mariadb-bin.000003 -vvv
# at 328
#151105 16:31:40 server id 1 end_log_pos 431 Query thread_id=1
exec_time=0 error_code=0
use `mydb`/*!*/;
SET TIMESTAMP=1446712300/*!*/;
CREATE TABLE tb1 (id int, name char(30))
/*!*/;
事件发生的日期和时间:151105 16:31:40
事件发生的服务器标识:server id 1
事件的结束位置:end_log_pos 431
事件的类型:Query
事件发生时所在服务器执行此事件的线程的ID:thread_id=1
语句的时间戳与将其写入二进制文件中的时间差:exec_time=0
错误代码:error_code=0
事件内容:
GTID:Global Transaction ID,mysql5.6以mariadb10以上版本专属属性:GTID
#TO删除某文件之前的日志文件
#BEFORE删除某时间点之前的日志文件
PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }
MariaDB [hellodb]> purge binary logs to 'mysql-bin.000003';
Query OK, 0 rows affected (0.006 sec)
-rw-rw---- 1 mysql mysql 4478 Nov 26 18:08 mysql-bin.000001
-rw-rw---- 1 mysql mysql 1805 Nov 26 18:15 mysql-bin.000002
-rw-rw---- 1 mysql mysql 1600 Nov 26 18:21 mysql-bin.000003
-rw-rw---- 1 mysql mysql 108 Nov 26 18:15 mysql-bin.index
[root@centos8 logbin]#ll
total 28
-rw-rw---- 1 mysql mysql 1600 Nov 26 18:21 mysql-bin.000003
-rw-rw---- 1 mysql mysql 36 Nov 26 18:29 mysql-bin.index
PURGE BINARY LOGS TO 'mariadb-bin.000003';#删除3之前的日志
PURGE BINARY LOGS BEFORE '2017-01-23';
PURGE BINARY LOGS BEFORE '2017-03-22 09:25:30';
#删除所有二进制日志文件,并重新生成日志文件(数据库主从复制),文件名从#开始记数,默认从1开始,一般是master主机第一次启动时执行,MariaDB10.1.6开始支持TO
RESET MASTER [TO #];
MariaDB [hellodb]> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000003 | 1600 |
+------------------+-----------+
1 row in set (0.000 sec)
MariaDB [hellodb]> reset master to 1213;
Query OK, 0 rows affected (0.007 sec)
MariaDB [hellodb]> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.001213 | 328 |
+------------------+-----------+
1 row in set (0.000 sec)
-rw-rw---- 1 mysql mysql 1600 Nov 26 18:21 mysql-bin.000003
-rw-rw---- 1 mysql mysql 36 Nov 26 18:29 mysql-bin.index
[root@centos8 logbin]#ll
total 28
-rw-rw---- 1 mysql mysql 328 Nov 26 18:31 mysql-bin.001213
-rw-rw---- 1 mysql mysql 36 Nov 26 18:31 mysql-bin.index
[root@centos8 logbin]#cat mysql-bin.index
/data/mysql/logbin/mysql-bin.001213
#生成新的二进制日志文件
FLUSH LOGS;
#执行一次,生成一个二进制日志文件;号码自增
MariaDB [hellodb]> flush logs;
Query OK, 0 rows affected (0.011 sec)
MariaDB [hellodb]> flush logs;
Query OK, 0 rows affected (0.010 sec)
MariaDB [hellodb]> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.001213 | 375 |
| mysql-bin.001214 | 418 |
| mysql-bin.001215 | 371 |
+------------------+-----------+
3 rows in set (0.000 sec)
MariaDB [hellodb]> flush logs;
Query OK, 0 rows affected (0.011 sec)
MariaDB [hellodb]> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.001213 | 375 |
| mysql-bin.001214 | 418 |
| mysql-bin.001215 | 418 |
| mysql-bin.001216 | 371 |
+------------------+-----------+
4 rows in set (0.000 sec)
[root@centos8 logbin]#ll
total 20
-rw-rw---- 1 mysql mysql 375 Nov 26 18:32 mysql-bin.001213
-rw-rw---- 1 mysql mysql 418 Nov 26 18:32 mysql-bin.001214
-rw-rw---- 1 mysql mysql 418 Nov 26 18:32 mysql-bin.001215
-rw-rw---- 1 mysql mysql 371 Nov 26 18:32 mysql-bin.001216
-rw-rw---- 1 mysql mysql 144 Nov 26 18:32 mysql-bin.index
[root@centos8 logbin]#cat mysql-bin.index
/data/mysql/logbin/mysql-bin.001213
/data/mysql/logbin/mysql-bin.001214
/data/mysql/logbin/mysql-bin.001215
/data/mysql/logbin/mysql-bin.001216
能容忍最多丢失多少数据(备份的频率)
恢复数据需要在多长时间内完成
需要恢复哪些数据
增量备份:仅备份最近一次完全备份或增量备份(如果存在增量)以来变化的数据,备份较快,还原复杂(先还原完全备份,再陆续还原增量备份)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wGaasggg-1576071563163)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191125155712266.png)]
差异备份:仅备份最近一次完全备份以来变化的数据,备份较慢(包含之前的备份。但是不能冒然删除),还原简单
冷备:读写操作均不可进行(数据库停止服务后备份)
温备:读操作可执行;但写操作不可执行
热备:读写操作均可执行
温备的持锁多久
备份产生的负载(服务访问的低峰期备份)
备份过程的时长
恢复过程的时长
数据
二进制日志(数据操作过程)、InnoDB的事务日志(存在未提交的事务或者未写入磁盘文件的事务)
程序代码(存储过程、函数、触发器、事件调度器)
服务器的配置文件
mysql> FLUSH TABLES WITH READ LOCK;
mysql> FLUSH LOGS;
mysql> SHOW MASTER STATUS;
mysql -e 'SHOW MASTER STATUS' > /PATH/TO/SOMEFILE
lvcreate -L # -s -p r -n NAME /DEV/VG_NAME/LV_NAME
mysql> UNLOCK TABLES;
#针对一个数据库中的所有表或特定表(打印在屏幕)
mysqldump [OPTIONS] database [tables]
#指定备份的数据库,包括create database语句
mysqldump [OPTIONS] –B DB1 [DB2 DB3...]
#备份所有数据库,含create database;备份的是mysql数据库和用户数据库;
#information_schema | performance_schema 数据库不备份,它是运行在内存中的,无需备份。
mysqldump [OPTIONS] –A [OPTIONS]
[root@CentOS7 ~]#mysqldump hellodb teachers
-- MySQL dump 10.16 Distrib 10.2.29-MariaDB, for Linux (x86_64)
--
-- Host: localhost Database: hellodb
-- ------------------------------------------------------
-- Server version 10.2.29-MariaDB
#信息描述
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `teachers`
--
#创建数据表table
DROP TABLE IF EXISTS `teachers`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `teachers` (
`TID` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(100) NOT NULL,
`Age` tinyint(3) unsigned NOT NULL,
`Gender` enum('F','M') DEFAULT NULL,
PRIMARY KEY (`TID`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `teachers`
--
#加写锁,添加记录
LOCK TABLES `teachers` WRITE;
/*!40000 ALTER TABLE `teachers` DISABLE KEYS */;
INSERT INTO `teachers` VALUES (1,'Song Jiang',45,'M'),(2,'Zhang Sanfeng',94,'M'),(3,'Miejue Shitai',77,'F'),(4,'Lin Chaoying',93,'F');
/*!40000 ALTER TABLE `teachers` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-11-26 20:19:28
https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html
-A, --all-databases #备份所有数据库,含create database
-B, --databases db_name… #指定备份的数据库,包括create database语句
-E, --events:#备份相关的所有event scheduler(计划任务)
-R, --routines:#备份所有存储过程和自定义函数
--triggers:#备份表相关触发器,默认启用,用--skip-triggers,不备份触发器
--default-character-set=utf8 #备份时指定字符集和数据库的字符集统一
#备份一个表,添加一次写锁(表);而备份时间较长,不加锁,会导致备份的数据不是同一个时间点数据
--master-data[=#]:
#此选项须启用二进制日志(温备)
#此选项会自动关闭--lock-tables功能,自动打开-x | --lock-all-tables功能(除非开启--single-transaction)|利用二进制日志文件还原数据最新状态
[root@centos8 data]#mysqldump --help | grep -A 3 '\-x'
-x, --lock-all-tables
Locks all tables across all databases. This is achieved
by taking a global read lock for the duration of the
whole dump. Automatically turns --single-transaction and
#1:所备份的数据之前加一条记录为CHANGE MASTER TO语句(主从复制,多台服务器备份使用),非注释,不指定#,默认为1
#2:记录为注释的CHANGE MASTER TO语句
*****************************************************************************************
-F, --flush-logs
#备份前滚动日志,锁定表完成后,执行flush logs命令,生成新的二进制日志文件,配合-A 或 -B 选项时,会导致刷新多次数据库。建议在同一时刻执行转储和日志刷新,可通过和--single-transaction或-x,--master-data 一起使用实现,此时只刷新一次日志
--compact #去掉注释,适合调试,生产不使用
-d, --no-data #只备份表结构
-t, --no-create-info #只备份数据,不备份create table
-n,--no-create-db #不备份create database,可被-A或-B覆盖
--flush-privileges #备份mysql或相关时需要使用
-f, --force #忽略SQL错误,继续执行
--hex-blob #使用十六进制符号转储二进制列,当有包括BINARY, VARBINARY,BLOB,BIT的数据类型的列时使用,避免乱码
-q, --quick #不缓存查询,直接输出,加快备份速度
#先显示需要备份的数据库
[root@CentOS7 data]#mysql -uroot -e 'show databases'
+--------------------+
| Database |
+--------------------+
| hellodb |
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
[root@CentOS7 data]#mysql -uroot -e 'show databases'|cat
Database
hellodb
information_schema
mysql
performance_schema
test
#grep工具筛选需要备份的数据库
[root@CentOS7 data]#mysql -uroot -e 'show databases'|grep -vE '^(Database|information_schema|performance_schema)'
hellodb
mysql
test
#循环语句while read,逐次读入数据库名并备份压缩
[root@CentOS7 data]$mysql -uroot -e 'show databases' | grep -vE '^(Database|information_schema|performance_schema)$' | while read db;do mysqldump -B $db | gzip > $db.sql.gz;done
[root@CentOS7 data]#ll
total 144
-rw-r--r-- 1 root root 1890 Nov 26 20:53 hellodb.sql.gz
-rw-r--r-- 1 root root 136531 Nov 26 20:53 mysql.sql.gz
-rw-r--r-- 1 root root 513 Nov 26 20:53 test.sql.gz
#循环语句for,逐次读入数据库名并备份压缩
[root@CentOS7 data]$for db in `mysql -uroot -e 'show databases'|grep -vE '^(Database|information_schema|performance_schema)$'`;do mysqldump -uroot -B $db | gzip > $db.sql.gz;done
[root@CentOS7 data]#ll
total 144
-rw-r--r-- 1 root root 1890 Nov 26 21:07 hellodb.sql.gz
-rw-r--r-- 1 root root 136533 Nov 26 21:07 mysql.sql.gz
-rw-r--r-- 1 root root 514 Nov 26 21:07 test.sql.gz
*****************************************************************************************
[root@CentOS7 data]$mysql -uroot -e 'show databases'|grep -Ev '^(Database|information_schema|performance_schema)$' | sed -rn 's#(.*)#mysqldump -B \1 | gzip > \1.sql.gz#p'
mysqldump -B hellodb | gzip > hellodb.sql.gz
mysqldump -B mysql | gzip > mysql.sql.gz
mysqldump -B test | gzip > test.sql.gz
#bash 执行语句
[root@CentOS7 data]$mysql -uroot -e 'show databases'|grep -Ev '^(Database|information_schema|performance_schema)$' | sed -rn 's#(.*)#mysqldump -B \1 | gzip > \1.sql.gz#p' | bash
[root@CentOS7 data]#ll
total 144
-rw-r--r-- 1 root root 1890 Nov 26 21:16 hellodb.sql.gz
-rw-r--r-- 1 root root 136533 Nov 26 21:16 mysql.sql.gz
-rw-r--r-- 1 root root 514 Nov 26 21:16 test.sql.gz
*****************************************************************************************
[root@CentOS7 data]$mysql -uroot -e 'show databases' | sed -rn '/^(Database|information_schema|performance_schema)$/!s#(.*)#mysqldump -B \1 | gzip > \1.sql.gz#p'
mysqldump -B hellodb | gzip > hellodb.sql.gz
mysqldump -B mysql | gzip > mysql.sql.gz
mysqldump -B test | gzip > test.sql.gz
#bash 执行语句
[root@CentOS7 data]$mysql -uroot -e 'show databases' | sed -rn '/^(Database|information_schema|performance_schema)$/!s#(.*)#mysqldump -B \1 | gzip > \1.sql.gz#p' | bash
[root@CentOS7 data]#ll -h
total 144K
-rw-r--r-- 1 root root 1.9K Nov 26 21:20 hellodb.sql.gz
-rw-r--r-- 1 root root 134K Nov 26 21:20 mysql.sql.gz
-rw-r--r-- 1 root root 513 Nov 26 21:20 test.sql.gz
#禁止访问数据库socket本地连接数据库
#二进制日志独立存放
[mysqld]
log-bin=/data/mysql/mysql-bin
#完全备份,并记录备份的二进制位置
mysqldump -A --master-data=2 | gzip > /backup/all_`date +%F`.sql.gz
#修改数据库
insert students (name,age,gender)value('mage',20,'M');
insert students (name,age,gender)value('wang',22,'M');
#损坏数据库
rm -rf /var/lib/mysql/*
#还原
cd /backup
gzip -d all_2019-11-25.sql.gz
#生成数据库相关文件
mysql_install_db --user=mysql
systemctl restart mariadb
MariaDB [(none)]> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 998 |
| mysql-bin.000002 | 28090 |
| mysql-bin.000003 | 342 |
+------------------+-----------+
3 rows in set (0.000 sec)
#禁用二进制日志
MariaDB [(none)]>set sql_log_bin=0;
#还原完全备份
MariaDB [(none)]>source /data/all_2019-11-25.sql
#查找二进制备份的文件位置 MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=328;
[root@centos8 ~]#grep '^-- CHANGE MASTER TO' /data/all_2019-11-25.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=328;
#二进制日志的备份:增量备份
[root@centos8 mysql]#mysqlbinlog mysql-bin.000001 --start-position=328 >/backup/inc.sql
#追加二进制备份
[root@centos8 mysql]#mysqlbinlog mysql-bin.000002 >> /backup/inc.sql
MariaDB [(none)]>set sql_log_bin=0;
MariaDB [(none)]>source /backup/inc.sql
-x,--lock-all-tables #加全局读锁,锁定所有库的所有表,同时加--single-transaction或--lock-tables选项会关闭此选项功能
#注意:数据量大时,可能会导致长时间无法并发访问数据库
-l,--lock-tables #对于需要备份的每个数据库,在启动备份之前分别锁定其所有表,默认为on,--skip-lock-tables选项可禁用,对备份MyISAM的多个库,可能会造成数据不一致
#注:以上选项对InnoDB表一样生效,实现温备,但不推荐使用
--single-transaction
#此选项Innodb中推荐使用,不适用MyISAM,此选项会开始备份前,先执行START TRANSACTION指令开启事务
#此选项通过在单个事务中转储所有表来创建一致的快照。 仅适用于存储在支持多版本控制的存储引擎中的表(目前只有InnoDB可以); 转储不保证与其他存储引擎保持一致。 在进行单事务转储时,要确保有效的转储文件(正确的表内容和二进制日志位置),没有其他连接应该使用以下语句:ALTER TABLE,DROP TABLE,RENAME TABLE,TRUNCATE TABLE,此选项和--lock-tables(此选项隐含提交挂起的事务)选项是相互排斥,备份大型表时,建议将--single-transaction选项和--quick结合一起使用
mysqldump –uroot –A –F –E –R --single-transaction --master-data=1 --flush-privileges --triggers --default-character-set=utf8 --hex-blob>${BACKUP}/fullbak_${BACKUP_TIME}.sql
mysqldump –uroot –A –F –E –R –x --master-data=1 --flush-privileges --triggers --default-character-set=utf8 --hex-blob >${BACKUP}/fullbak_${BACKUP_TIME}.sql
范例: 完全备份和还原
#开启二进制日志
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
log-bin
#备份
[root@centos8 ~]#mysqldump -uroot -p -A -F --single-transaction --master-data=2 |gzip > /backup/all-`date +%F`.sql.gz
#还原
[root@centos8 backup]#dnf install mariadb-server
[root@centos8 backup]#gzip -d all-2019-11-27.sql.gz
[root@centos8 ~]#mysql
MariaDB [(none)]> set sql_log_bin=off;
MariaDB [(none)]> source /backup/all-2019-11-27.sql
MariaDB [(none)]> set sql_log_bin=on;
范例:mysqldump 和二进制日志结合实现增量备份
[root@centos8 ~]#mysqldump -uroot -p -A -F --single-transaction --master-data=2
|gzip > /backup/all-`date +%F`.sql.gz
#观察备份文件中的二进制文件和位置,将之后的二进制日志进行复制备份
[root@centos8 ~]#cp /var/lib/mysql/mariadb-bin.000003 /backup
[root@centos8 ~]#mysqlbinlog --start-position=389 /backup/mariadb-bin.000003 >/backup/inc.sql
范例:将误删除了的某个表进行还原
#完全备份
[root@centos8 ~]#mysqldump -uroot -p -A -F --single-transaction --master-data=2
> /backup/allbackup_`date +%F_%T`.sql
[root@centos8 ~]#ll /backup/
total 2992
-rw-r--r-- 1 root root 3060921 Nov 27 10:20 allbackup_2019-11-27_10:20:08.sql
#完全备份后数据更新
MariaDB [testdb]> insert student_info (stu_name) values('rose');
Query OK, 1 row affected (0.001 sec)
MariaDB [testdb]> insert student_info (stu_name) values('jack');
Query OK, 1 row affected (0.001 sec)
#10:00误删除了一个重要的表
MariaDB [testdb]> drop table student_info;
Query OK, 0 rows affected (0.021 sec)
#后续其它表继续更新
MariaDB [testdb]> use hellodb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [hellodquib]> insert teachers (name,age,gender)values('wang',30,'M');
Query OK, 1 row affected (0.002 sec)
MariaDB [hellodb]> insert teachers (name,age,gender)values('mage',28,'M');><
MariaDB [hellodb]> select mys* from teachers;
+-----+---------------+-----+--------+
| TID | Name | Age | Gender |
+-----+---------------+-----+--------+
| 1 | Song Jiang | 45 | M |
| 2 | Zhang Sanfeng | 94 | M |
| 3 | Miejue Shitai | 77 | F |
| 4 | Lin Chaoying | 93 | F |
| 5 | wang | 30 | M |
| 6 | mage | 28 | M |
+-----+---------------+-----+--------+
6 rows in set (0.001 sec)
#10:10发现表删除,进行还原
#停止数据库访问
#从完全备份中,找到二进制位置
[root@centos8 ~]#grep '\-\- CHANGE MASTER TO' /backup/allbackup_2019-11-
27_10\:20\:08.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mariadb-bin.000003', MASTER_LOG_POS=389;
#备份从完全备份后的二进制日志
[root@centos8 ~]#mysqlbinlog --start-position=389 /var/lib/mysql/mariadbbin.000003 > /backup/inc.sql
#找到误删除的语句,从备份中删除此语句
[root@centos8 ~]#vim /data/inc.sql
#DROP TABLE `student_info` /* generated by server */
#利用完全备份和修改过的二进制日志进行还原
[root@centos8 ~]#mysql -uroot -p
MariaDB [hellodb]> set sql_log_bin=0;
MariaDB [hellodb]> source /backup/allbackup_2019-11-27_10:20:08.sql;
MariaDB [hellodb]> source /backup/inc.sql
MariaDB [hellodb]> set sql_log_bin=1;
innobackupex 脚本用来备份非 InnoDB 表,同时会调用 xtrabackup 命令来备份 InnoDB 表,还会和MySQL Server 发送命令进行交互,如加全局读锁(FTWRL)、获取位点(SHOW SLAVE STATUS)等。即innobackupex是在 xtrabackup 之上做了一层封装实现的
xtrabackup版本升级到2.4后,相比之前的2.1有了比较大的变化:innobackupex 功能全部集成到xtrabackup 里面,只有一个 binary程序,另外为了兼容考虑,innobackupex作为 xtrabackup 的软链接,即xtrabackup现在支持非Innodb表备份,并且 Innobackupex 在下一版本中移除,建议通过xtrabackup替换innobackupex
innobackupex [option] BACKUP-ROOT-DIR
--user:#该选项表示备份账号
--password:#该选项表示备份的密码
--host:#该选项表示备份数据库的地址
--databases:#该选项接受的参数为数据库名,如果要指定多个数据库,彼此间需要以空格隔开;
如:"xtra_test dba_test",同时,在指定某数据库时,也可以只指定其中的某张表。
如:"mydatabase.mytable"。该选项对innodb引擎表无效,还是会备份所有innodb表
--defaults-file:#该选项指定从哪个文件读取MySQL配置,必须放在命令行第一个选项位置
--incremental:#该选项表示创建一个增量备份,需要指定--incremental-basedir
--incremental-basedir:#该选项指定为前一次全备份或增量备份的目录,与--incremental同时使用
--incremental-dir:#该选项表示还原时增量备份的目录
--include=name:#指定表名,格式:databasename.tablename
#将完全备份的数据放在第三方目录中
#事务未完成状态(后一个增量备份包含前一个增量备份的未完成的事务,所以之前的完全备份和增量备份不需要将事务rollback,但是最后一个增量备份,数据要回滚,加此选项)
innobackupex --apply-log [option] BACKUP-DIR
--apply-log:#一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处理不一致状态。此选项作用是通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态
--use-memory:#和--apply-log选项一起使用,当prepare 备份时,做crash recovery分配的内存大小,单位字节,也可1MB,1M,1G,1GB等,推荐1G
--export:#表示开启可导出单独的表之后再导入其他Mysql中
--redo-only:#此选项在prepare base full backup,往其中合并增量备份时候使用,但不包括对最后一个增量备份的合并(不回滚事务)
innobackupex --copy-back [选项] BACKUP-DIR
innobackupex --move-back [选项] [--defaults-group=GROUP-NAME] BACKUP-DIR
--copy-back:#做数据恢复时将备份数据文件拷贝到MySQL服务器的datadir
--move-back:#这个选项与--copy-back相似,唯一的区别是它不拷贝文件,而是移动文件到目的地。这个选项移除backup文件,用时候必须小心。使用场景:没有足够的磁盘空间同事保留数据文件和Backup副本
--force-non-empty-directories #指定该参数时候,使得innobackupex --copy-back或--moveback选项转移文件到非空目录,已存在的文件不会被覆盖。如果--copy-back和--move-back文件需要从备份目录拷贝一个在datadir已经存在的文件,会报错失败
innobackupex --user=root /backup
scp -r /backup/2018-02-23_11-55-57/ 目标主机:/data/
#预准备
innobackupex --apply-log /data/2018-02-23_11-55-57/
#还原过程
systemctl stop mariadb
rm -rf /var/lib/mysql/*
innobackupex --copy-back /data/2018-02-23_11-55-57/
chown -R mysql.mysql /var/lib/mysql/
systemctl start mariadb
innobackupex /backup
mkdir /backup/inc{1,2}
#修改数据库内容
innobackupex --incremental /backup/inc1 --incremental-basedir=/backup/2018-02-
23_14-21-42(完全备份生成的路径)
#再次修改数据库内容
innobackupex --incremental /backup/inc2 --incrementalbasedir=/backup/inc1/2018-02-23_14-26-17 (上次增量备份生成的路径)
scp -r /backup/* 目标主机:/data/
#预准备过程
innobackupex --apply-log --redo-only /data/2018-02-23_14-21-42/
innobackupex --apply-log --redo-only /data/2018-02-23_14-21-42/ --incrementaldir=/data/inc1/2018-02-23_14-26-17
innobackupex --apply-log /data/2018-02-23_14-21-42/ --incrementaldir=/data/inc2/2018-02-23_14-28-29/
#还原过程
不启动mariadb
systemctl stop mariadb
rm -rf /var/lib/mysql/*
innobackupex --copy-back /data/2018-02-23_14-21-42/
chown -R mysql.mysql /var/lib/mysql/
systemctl start mariadb
1 在原主机做完全备份到/backup
#/backup目录不需事先创建
yum -y install perl-Digest-MD5 #出错处理
xtrabackup --backup --target-dir=/backup/
scp -r /backup/* 目标主机:/backup
2 在目标主机上
1)预准备:确保数据一致,提交完成的事务,回滚未完成的事务(无需输入密码)
xtrabackup --prepare --target-dir=/backup/
2)复制到数据库目录
注意:数据库目录必须为空,MySQL服务不能启动
xtrabackup --copy-back --target-dir=/backup/
3)还原属性
chown -R mysql:mysql /var/lib/mysql
4)启动服务
systemctl start mariadb
yum install libncurses.so.5
5)
[root@centos8 ~]#vim /etc/my.cnf
[mysqld]
socket=/data/mysql2/mysql.sock
user=mysql
symbolic-links=0
datadir=/data/mysql2
innodb_file_per_table=1
pid_file=/data/mysql2/mysql.pid
[client]
port=3306
socket=/data/mysql2/mysql.sock
[mysqld_safe]
log-error=/var/log/mysqld.log
6)服务器可以重新启动,但是无法登陆到数据库:客户端mysql缺少库文件,就安装mariadb的客户端指定客户端路径是/usr/bin(mysql5.7.28的/usr/local/mysql/bin中缺少库文件,无法使用,就不指定数据库命令执行的PATH到文件)
[root@centos8 ~]#mysql -pyanyi -uroot
mysql: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory
#mysql客户端库文件出错
[root@centos8 bin]#ldd mysql
linux-vdso.so.1 (0x00007fff47eb3000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f6573162000)
librt.so.1 => /lib64/librt.so.1 (0x00007f6572f59000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f6572d55000)
libncurses.so.5 => not found
libtinfo.so.5 => not found
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f65729c0000)
libm.so.6 => /lib64/libm.so.6 (0x00007f657263e000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f6572426000)
libc.so.6 => /lib64/libc.so.6 (0x00007f6572062000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6573382000)
#mysqld没有问题
[root@centos8 bin]#ldd mysqld
linux-vdso.so.1 (0x00007fffeeb05000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f29cbe5f000)
libaio.so.1 => /lib64/libaio.so.1 (0x00007f29cbc5c000)
libnuma.so.1 => /lib64/libnuma.so.1 (0x00007f29cba50000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f29cb827000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f29cb623000)
librt.so.1 => /lib64/librt.so.1 (0x00007f29cb41a000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f29cb085000)
libm.so.6 => /lib64/libm.so.6 (0x00007f29cad03000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f29caaeb000)
libc.so.6 => /lib64/libc.so.6 (0x00007f29ca727000)
/lib64/ld-linux-x86-64.so.2 (0x00007f29cc07f000)
#查看mysql的路径
[root@centos8 bin]#which mysql
/usr/local/mysql/bin/mysql
#指定mysql的路径,或者删除文件/etc/profile.d/mysql.sh
[root@centos8 bin]#vim /etc/profile.d/mysql.sh
export PATH=/usr/bin:$PATH
[root@centos8 bin]#. /etc/profile.d/mysql.sh
[root@centos8 ~]#which mysql
/usr/bin/mysql
[root@centos8 ~]#mysql -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.28 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
1 备份过程
1)完全备份:xtrabackup --backup --target-dir=/backup/base
2)第一次修改数据
3)第一次增量备份
xtrabackup --backup --target-dir=/backup/inc1 --incremental-basedir=/backup/base
4)第二次修改数据
5)第二次增量
xtrabackup --backup --target-dir=/backup/inc2 --incremental-basedir=/backup/inc1
6)scp -r /backup/* 目标主机:/backup/
#备份过程生成三个备份目录
/backup/{base,inc1,inc2}
2还原过程(都是还原备份到base目录下在复制)
1)预准备完成备份,此选项--apply-log-only 阻止回滚未完成的事务
xtrabackup --prepare --apply-log-only --target-dir=/backup/base
2)合并第1次增量备份到完全备份,
xtrabackup --prepare --apply-log-only --target-dir=/backup/base --incremental-dir=/backup/inc1
3)合并第2次增量备份到完全备份:最后一次还原不需要加选项--apply-log-only
xtrabackup --prepare --target-dir=/backup/base --incremental-dir=/backup/inc2
4)复制到数据库目录,注意数据库目录必须为空,MySQL服务不能启动
xtrabackup --copy-back --target-dir=/backup/base
5)还原属性:chown -R mysql:mysql /var/lib/mysql
6)启动服务:systemctl start mariadb
#导出
1 单表备份
innobackupex --include='hellodb.students' /backups
2备份表结构
mysql -e 'show create table hellodb.students' > student.sql
3删除表
mysql -e 'drop table hellodb.students‘
#导入
4 innobackupex --apply-log --export /backups/2018-02-23_15-03-23/
示例: xtrabackup单表导出和导入
5 创建表
mysql>CREATE TABLE `students` (
`StuID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(50) NOT NULL,
`Age` tinyint(3) unsigned NOT NULL,
`Gender` enum('F','M') NOT NULL,
`ClassID` tinyint(3) unsigned DEFAULT NULL,
`TeacherID` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`StuID`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8
6 删除表空间
alter table students discard tablespace;
7 cp /backups/2018-02-23_15-03-23/hellodb/students.{cfg,exp,ibd}
/var/lib/mysql/hellodb/
8 chown -R mysql.mysql /var/lib/mysql/hellodb/
9 mysql>alter table students import tablespace;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-32fEC0lO-1576071563164)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191127151353655.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-czo3smIg-1576071563165)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191123153122196.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ps18VAuH-1576071563165)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191123153209196.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JsAyPlVm-1576071563166)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191123153315627.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tGKqMhcL-1576071563167)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191123153401376.png)]
主节点:
从节点:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-74UmQB80-1576071563167)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191127155412263.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vO6KvNBv-1576071563168)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191127155852458.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V56vHbB6-1576071563169)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191123153824287.png)]
[mysqld]
log_bin
[mysqld]
#默认是1
server_id=#
log-basename=master #可选项,设置datadir中日志名称,确保不依赖主机名
server-id的取值范围
#只有复制权限的用户账号
GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'HOST' IDENTIFIED BY 'replpass';
[mysqld]
server_id=# #为当前节点设置一个全局唯一的ID号
read_only=ON #设置数据库只读(只针对普通用户,对supper user无效)
relay_log=relay-log #relay log的文件路径,默认值hostname-relay-bin
relay_log_index=relay-log.index #默认值hostname-relay-bin.index
CHANGE MASTER TO MASTER_HOST='host',
MASTER_USER='repluser',
MASTER_PASSWORD='replpass',
#二进制日志文件名
MASTER_LOG_FILE=' mariadb-bin.xxxxxx',
#二进制日志位置
MASTER_LOG_POS=#;
#启动线程|第一次手动启动,重启服务自动启动
START SLAVE [IO_THREAD|SQL_THREAD];
#查看从服务器状态
SHOW SLAVE STATUS;
#主节点
[root@master ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=8
log-bin
#重启MariaDB
[root@master ~]#systemctl restart mariadb
[root@master ~]#mysql
#创建仅复制权限的账号
MariaDB [(none)]> grant replication slave on *.* to repluser@'192.168.39.%'
identified by 'magedu';
#查看二进制文件和位置
MariaDB [(none)]> show master logs;
+--------------------+-----------+
| Log_name | File_size |
+--------------------+-----------+
| mariadb-bin.000001 | 28052 |
| mariadb-bin.000002 | 545 |
+--------------------+-----------+
2 rows in set (0.001 sec)
********************************************************************
#从节点
[root@slave ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=18
[root@slave ~]#systemctl restart mariadb
[root@slave1 ~]#mysql
#查看帮助如何建立主从连接
MariaDB [(none)]> help change master to
CHANGE MASTER TO
MASTER_HOST='master2.mycompany.com',
MASTER_USER='replication',
MASTER_PASSWORD='bigs3cret',
MASTER_PORT=3306,
MASTER_LOG_FILE='master2-bin.001',
MASTER_LOG_POS=4,
MASTER_CONNECT_RETRY=10;
#实现主从连接
MariaDB [(none)]> CHANGE MASTER TO
MASTER_HOST='192.168.39.8',
MASTER_USER='repluser',
MASTER_PASSWORD='magedu',
MASTER_PORT=3306,
MASTER_LOG_FILE='mariadb-bin.000002',
MASTER_LOG_POS=545;
#启动主从复制线程
MariaDB [(none)]> start slave;
Query OK, 0 rows affected, 1 warning (0.000 sec)
#查看从服务器状态
MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.39.8
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60 #连接失败后重试
Master_Log_File: mariadb-bin.000002 #主节点复制的二进制日志
Read_Master_Log_Pos: 26987890 #主节点二进制位置
Relay_Log_File: mariadb-relay-bin.000002 #从节点中继日志
Relay_Log_Pos: 26987902 #从节点中继日志位置
Relay_Master_Log_File: mariadb-bin.000002
Slave_IO_Running: Yes #负责与主服务器的io通信()
Slave_SQL_Running: Yes #负责从服务器的数据生成(利用中继日志生成数据)
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 26987890
Relay_Log_Space: 26988213
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0 #复制的延迟时间(会随服务器的负载变化)
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 8
Master_SSL_Crl:
Master_SSL_Crlpath:
Using_Gtid: No
Gtid_IO_Pos:
Replicate_Do_Domain_Ids:
Replicate_Ignore_Domain_Ids:
Parallel_Mode: conservative
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the
slave I/O thread to update it
Slave_DDL_Groups: 34
Slave_Non_Transactional_Groups: 0
Slave_Transactional_Groups: 100006
1 row in set (0.000 sec)
通过备份恢复数据至从服务器
复制起始位置为备份时的二进制日志文件及其POS
#在主服务器完全备份
[root@master ~]#mysqldump -A -F --single-transaction --master-data=1 >
/backup/fullbackup_`date +%F_%T`.sql
[root@master ~]#ll /backup/
total 2988
-rw-r--r-- 1 root root 3055918 Nov 27 17:41 fullbackup_2019-11-27_17:41:17.sql
#将完全备份传输到从节点
[root@master ~]#scp /backup/fullbackup_2019-11-27_17\:41\:17.sql
192.168.8.11:/data/
#将完全备份还原到新的从节点
[root@slave ~]#dnf -y install mariadb-server
[root@slave ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=11
read-only
[root@slave ~]#systemctl restart mariadb
#配置从节点,从完全备份的位置之后开始复制
[root@slave ~]#grep '^CHANGE MASTER' /data/fullbackup_2019-11-27_17\:41\:17.sql
CHANGE MASTER TO MASTER_LOG_FILE='mariadb-bin.000003', MASTER_LOG_POS=389;
#修改完全备份文件添加复制账号和。创立主从连接
[root@slave ~]#vim /data/fullbackup_2019-11-27_17\:41\:17.sql
CHANGE MASTER TO
MASTER_HOST='192.168.8.10',
MASTER_USER='repluser',
MASTER_PASSWORD='magedu',
MASTER_PORT=3306,
MASTER_LOG_FILE='mariadb-bin.000003', MASTER_LOG_POS=389;
#读取文件到从节点
[root@slave ~]#mysql < /data/fullbackup_2019-11-27_17\:41\:17.sql
[root@slave ~]#mysql
#查看从服务器状态,未启动主从复制线程
MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 192.168.8.10
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mariadb-bin.000003
Read_Master_Log_Pos: 389
Relay_Log_File: mariadb-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mariadb-bin.000003
Slave_IO_Running: No
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 389
Relay_Log_Space: 256
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0
Master_SSL_Crl:
Master_SSL_Crlpath:
Using_Gtid: No
Gtid_IO_Pos:
Replicate_Do_Domain_Ids:
Replicate_Ignore_Domain_Ids:
Parallel_Mode: conservative
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
Slave_DDL_Groups: 0
Slave_Non_Transactional_Groups: 0
Slave_Transactional_Groups: 0
1 row in set (0.000 sec)
#启动主从复制线程
MariaDB [(none)]> start slave;
read_only=ON
#注意:此限制对拥有SUPER权限的用户均无效
注意:以下命令会阻止所有用户, 包括主服务器复制的更新
mysql> FLUSH TABLES WITH READ LOCK;
RESET SLAVE #从服务器清除master.info ,relay-log.info, relay log ,开始新的relay log
RESET SLAVE ALL #清除所有从服务器上设置的主服务器同步信息,如PORT, HOST, USER和 PASSWORD 等
sql_slave_skip_counter = N
#重启主从复制
start slave
MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.39.8
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mariadb-bin.000002
Read_Master_Log_Pos: 26988271
Relay_Log_File: mariadb-relay-bin.000003
Relay_Log_Pos: 557
Relay_Master_Log_File: mariadb-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1007
Last_Error: Error 'Can't create database 'db4'; database
exists' on query. Default database: 'db4'. Query: 'create database db4'
Skip_Counter: 0
Exec_Master_Log_Pos: 26988144
Relay_Log_Space: 26988895
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 1007 #错误编码
Last_SQL_Error: Error 'Can't create database 'db4'; database
exists' on query. Default database: 'db4'. Query: 'create database db4'
Replicate_Ignore_Server_Ids:
Master_Server_Id: 8
Master_SSL_Crl:
Master_SSL_Crlpath:
Using_Gtid: No
Gtid_IO_Pos:
Replicate_Do_Domain_Ids:
Replicate_Ignore_Domain_Ids:
Parallel_Mode: conservative
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
Slave_DDL_Groups: 37
Slave_Non_Transactional_Groups: 0
Slave_Transactional_Groups: 100006
1 row in set (0.000 sec)
#方法1
MariaDB [(none)]> stop slave;#复合冲突后停止线程
MariaDB [(none)]> set global sql_slave_skip_counter=1;
MariaDB [(none)]> start slave;
#方法2
[root@slave1 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
slave_skip_errors=1007|ALL
[root@slave1 ~]#systemctl restart mariadb
保证主从复制的事务安全
sync_binlog=1 #每次写后立即同步二进制日志到磁盘,性能差
#如果用到的为InnoDB存储引擎:
innodb_flush_log_at_trx_commit=1 #每次事务提交立即同步日志写磁盘
innodb_support_xa=ON #分布式事务MariaDB10.3.0废除
sync_master_info=# #次事件后master.info同步到磁盘
skip-slave-start=ON #不自动启动slave
sync_relay_log=# N次写后同步relay log到磁盘
sync_relay_log_info=# N次事务后同步relay-log.info到磁盘
#中继日志生成的数据不写入二进制日志;
[mysqld]
log_bin
log_slave_updates #将中继日志产生的数据库更新写入到二进制日志,再传送到下一个从服务器的中继日志
#三台主机实现级联复制
192.168.52.71 master
192.168.52.72 级联slave
192.168.52.73 slave
#在master实现
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=8
log-bin
[root@centos8 ~]#systemctl restart mariadb
[root@centos8 ~]#mysql
MariaDB [(none)]> grant replication slave on *.* to repluser@'192.168.100.%'
identified by 'magedu';
[root@centos8 ~]#mysqldump -A -F --single-transaction --master-data=1 >
/data/all.sql
[root@centos8 ~]#scp /data/all.sql 192.168.100.18:/data
[root@centos8 ~]#scp /data/all.sql 192.168.100.28:/data
#在中间级联slave实现
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=18
log-bin
log_slave_updates #级联复制中间节点的必选项
[root@centos8 ~]#systemctl restart mariadb
#还原数据库
[root@centos8 ~]#vim /data/all.sql
CHANGE MASTER TO
MASTER_HOST='192.168.100.8',
MASTER_USER='repluser',
MASTER_PASSWORD='magedu',
MASTER_PORT=3306,
MASTER_LOG_FILE='mariadb-bin.000001
', MASTER_LOG_POS=344;
[root@centos8 ~]#mysql
MariaDB [(none)]> set sql_log_bin=0;#临时禁用二进制
MariaDB [(none)]> source /data/all.sql
MariaDB [(none)]> show master logs; #记录二进制位置,给第三个节点使用
MariaDB [(none)]> set sql_log_bin=1;#开启二进制
MariaDB [(none)]> start slave;
#在第三个节点slave上实现
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=28
[root@centos8 ~]#systemctl restart mariadb
[root@centos8 ~]#vim /data/all.sql
CHANGE MASTER TO
MASTER_HOST='192.168.100.18',
MASTER_USER='repluser',
MASTER_PASSWORD='magedu',
MASTER_PORT=3306,
MASTER_LOG_FILE='mariadb-bin.000002', MASTER_LOG_POS=344;
[root@centos8 ~]#mysql < /data/all.sql
[root@centos8 ~]#mysql -e 'start slave;'
主主复制:两个节点,都可以更新数据,互为主从
容易产生的问题:数据不一致;因此慎用
考虑要点:自动增长id
auto_increment_offset=1 #开始点
auto_increment_increment=2 #增长幅度
auto_increment_offset=2
auto_increment_increment=2
各节点使用一个惟一server_id
都启动binary log和relay log
创建拥有复制权限的用户账号
定义自动增长id字段的数值范围各为奇偶
均把对方指定为主节点,并启动复制线程(各自为从服务器start slave)
#在第一个master节点上实现
[root@master1 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=8
log-bin
auto_increment_offset=1 #开始点
auto_increment_increment=2 #增长幅度
[root@master1 ~]#systemctl start mariadb
[root@master1 ~]#mysql
MariaDB [(none)]> show master logs;
+--------------------+-----------+
| Log_name | File_size |
+--------------------+-----------+
| mariadb-bin.000001 | 28303 |
| mariadb-bin.000002 | 386 |
+--------------------+-----------+
2 rows in set (0.000 sec)
MariaDB [(none)]> grant replication slave on *.* to repluser@'192.168.100.%'
identified by 'magedu';
#在第二个master节点上实现
[rootmaster2 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=18
log-bin
auto_increment_offset=2 #开始点
auto_increment_increment=2 #增长幅度
[root@master2 ~]#systemctl start mariadb
[root@master2 ~]#mysql
MariaDB [(none)]> CHANGE MASTER TO
-> MASTER_HOST='192.168.100.8',
-> MASTER_USER='repluser',
-> MASTER_PASSWORD='magedu',
-> MASTER_PORT=3306,
-> MASTER_LOG_FILE='mariadb-bin.000002',
-> MASTER_LOG_POS=386;
Query OK, 0 rows affected (0.019 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.003 sec)
MariaDB [(none)]> show master logs; #查看二进制位置
+--------------------+-----------+
| Log_name | File_size |
+--------------------+-----------+
| mariadb-bin.000001 | 28303 |
| mariadb-bin.000002 | 344 |
+--------------------+-----------+
2 rows in set (0.001 sec)
#在第一个master节点上实现
MariaDB [(none)]> CHANGE MASTER TO
-> MASTER_HOST='192.168.100.18',
-> MASTER_USER='repluser',
-> MASTER_PASSWORD='magedu',
-> MASTER_PORT=3306,
-> MASTER_LOG_FILE='mariadb-bin.000002',
-> MASTER_LOG_POS=344;
Query OK, 0 rows affected (0.007 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.002 sec)
MariaDB [db1]> create table t1(id int auto_increment primary key,name char(10));
#两个节点分别插入数据
#在第一个节点上执行
MariaDB [db1]> create database db1;
MariaDB [db1]> insert t1 (name) values('user1');
#在第二个节点上执行
MariaDB [db1]> insert t1 (name) values('user2');
#两个节点同时插入数据
MariaDB [db1]> insert t1 (name) values('userX');
MariaDB [db1]> select * from t1;
+----+-------+
| id | name |
+----+-------+
| 1 | user1 |
| 2 | user2 |
| 3 | userX |
| 4 | userX |
+----+-------+
4 rows in set (0.001 sec)
#两个节点同时创建数据库,发生复制冲突
MariaDB [db1]> create database db2;
MariaDB [db1]> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.100.18
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mariadb-bin.000002
Read_Master_Log_Pos: 1029
Relay_Log_File: mariadb-relay-bin.0000027.1.6 半同步复制
Relay_Log_Pos: 1110
Relay_Master_Log_File: mariadb-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1007
Last_Error: Error 'Can't create database 'db2'; database
exists' on query. Default database: 'db2'. Query: 'create database db2'
Skip_Counter: 0
Exec_Master_Log_Pos: 897
Relay_Log_Space: 1553
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 1007
Last_SQL_Error: Error 'Can't create database 'db2'; database
exists' on query. Default database: 'db2'. Query: 'create database db2'
Replicate_Ignore_Server_Ids:
Master_Server_Id: 18
Master_SSL_Crl:
Master_SSL_Crlpath:
Using_Gtid: No
Gtid_IO_Pos:
Replicate_Do_Domain_Ids:
Replicate_Ignore_Domain_Ids:
Parallel_Mode: conservative
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
Slave_DDL_Groups: 2
Slave_Non_Transactional_Groups: 0
Slave_Transactional_Groups: 2
1 row in set (0.003 sec)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YD5CJXaQ-1576071563170)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191123155817815.png)]
官方文档: https://mariadb.com/kb/en/library/semisynchronous-replication/
#主服务器配置:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; #安装插件
UNINSTALL PLUGIN rpl_semi_sync_master ;#卸载插件
SHOW PLUGINS; #查看插件
SET GLOBAL rpl_semi_sync_master_enabled=1;
SET GLOBAL rpl_semi_sync_master_timeout = 1000; #超时长1s,默认值为10s
SHOW GLOBAL VARIABLES LIKE '%semi%';
SHOW GLOBAL STATUS LIKE '%semi%';
#从服务器配置:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_slave_enabled=1;
#mariadb-10.3版以后
#主服务器配置:
[mysqld]
plugin_load_add = semisync_master
#从服务器配置:
[mysqld]
plugin_load_add = semisync_slave
#在master实现,启用半同步功能
[root@master ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=8
log-bin
plugin_load_add = semisync_master
rpl_semi_sync_master_enabled=ON
rpl_semi_sync_master_timeout=3000 #设置3s内无法同步,也将返回成功信息给客户端
[root@centos8 ~]#systemctl restart mariadb
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE '%semi%';
+---------------------------------------+--------------+
| Variable_name | Value |
+---------------------------------------+--------------+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | 3000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_COMMIT |
| rpl_semi_sync_slave_delay_master | OFF |
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_kill_conn_timeout | 5 |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------------+--------------+
9 rows in set (0.002 sec)
MariaDB [(none)]> SHOW GLOBAL STATUS LIKE '%semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 0 |
| Rpl_semi_sync_master_get_ack | 0 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 0 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_request_ack | 0 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
| Rpl_semi_sync_slave_send_ack | 0 |
| Rpl_semi_sync_slave_status | OFF |
+--------------------------------------------+-------+
18 rows in set (0.001 sec)
#在其它所有slave节点上都实现,启用半同步功能
[root@slave ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=18
plugin_load_add = semisync_slave
rpl_semi_sync_slave_enabled=ON
[root@slave ~]#systemctl restart mariadb
[root@slave ~]#mysql
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE '%semi%';
+---------------------------------------+--------------+
| Variable_name | Value |
+---------------------------------------+--------------+
| rpl_semi_sync_master_enabled | OFF |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_COMMIT |
| rpl_semi_sync_slave_delay_master | OFF |
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_kill_conn_timeout | 5 |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------------+--------------+
9 rows in set (0.001 sec)
MariaDB [(none)]> SHOW GLOBAL STATUS LIKE '%semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 0 |
| Rpl_semi_sync_master_get_ack | 0 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 0 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_request_ack | 0 |
| Rpl_semi_sync_master_status | OFF |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
| Rpl_semi_sync_slave_send_ack | 0 |
| Rpl_semi_sync_slave_status | ON |
+--------------------------------------------+-------+
18 rows in set (0.001 sec)
MariaDB [(none)]>
#在master上实现
MariaDB [db1]> SHOW GLOBAL STATUS LIKE '%semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 2 | #两个从节点
| Rpl_semi_sync_master_get_ack | 4 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 4 |
| Rpl_semi_sync_master_no_times | 1 |
| Rpl_semi_sync_master_no_tx | 1 |
| Rpl_semi_sync_master_request_ack | 3 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 1177 |
| Rpl_semi_sync_master_tx_wait_time | 2355 |
| Rpl_semi_sync_master_tx_waits | 2 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 2 |
| Rpl_semi_sync_slave_send_ack | 0 |
| Rpl_semi_sync_slave_status | OFF |
+--------------------------------------------+-------+
18 rows in set (0.001 sec)
#测试
#在master实现,创建数据库,立即成功
MariaDB [db1]> create database db2;
Query OK, 1 row affected (0.004 sec)
#在所有slave节点实现,停止复制线程
MariaDB [(none)]> stop slave;
Query OK, 0 rows affected (0.011 sec)
#在master实现,创建数据库,等待3s才能成功
MariaDB [db1]> create database db3;
Query OK, 1 row affected (3.003 sec)
#在任意一个slave节点实现,恢复复制线程
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.006 sec)
#在master实现,创建数据库,立即成功
MariaDB [db1]> create database db4;
Query OK, 1 row affected (0.002 sec)
vim /etc/my.cnf
binlog-do-db = #数据库白名单列表,多个数据库需多行实现
binlog-ignore-db = #数据库黑名单列表
replicate_do_db= #指定复制库的白名单
replicate_ignore_db= #指定复制库黑名单
replicate_do_table= #指定复制表的白名单
replicate_ignore_table= #指定复制表的黑名单
replicate_wild_do_table= foo%.bar% #支持通配符
replicate_wild_ignore_table=
MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.52.71
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: CentOS7-bin.000002
Read_Master_Log_Pos: 19679136
Relay_Log_File: CentOS7-relay-bin.000010
Relay_Log_Pos: 557
Relay_Master_Log_File: CentOS7-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: db1 #指定复制库的白名单
Replicate_Ignore_DB: #指定复制库黑名单
Replicate_Do_Table: #指定复制表的白名单
Replicate_Ignore_Table: #指定复制表的黑名单
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
#设置白名db3,但是在master的db1更新db3的数据无法同步
MariaDB [db1]> create table db3.t1(id int);
[root@centos8 ~]#mkdir /etc/my.cnf.d/ssl/
[root@centos8 ~]#cd /etc/my.cnf.d/ssl/
[root@centos8 ssl]#openssl genrsa 2048 > cakey.pem
Generating RSA private key, 2048 bit long modulus (2 primes)
...+++++
..........................+++++
e is 65537 (0x010001)
[root@centos8 ssl]#openssl req -new -x509 -key cakey.pem --out cacert.pem -days
3650
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:magedu
Organizational Unit Name (eg, section) []:opt
Common Name (eg, your name or your server's hostname) []:ca.magedu.org
Email Address []:
[root@centos8 ssl]#ls
cacert.pem cakey.pem
[root@centos8 ssl]#openssl req -newkey rsa:2048 -nodes -keyout master.key >
master.csr
Generating a RSA private key
..+++++
................................................................................
.................+++++
writing new private key to 'master.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:magedu
Organizational Unit Name (eg, section) []:opt
Common Name (eg, your name or your server's hostname) []:master.magedu.org
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@centos8 data]#ls
cacert.pem cakey.pem master.csr master.key
[root@centos8 ssl]#openssl x509 -req -in master.csr -CA cacert.pem -CAkey
cakey.pem --set_serial 01 > master.crt
Signature ok
subject=C = CN, ST = beijing, L = beijing, O = magedu, OU = opt, CN =
master.magedu.org
Getting CA Private Key
[root@centos8 ssl]#ls
cacert.pem cakey.pem master.crt master.csr master.key
[root@centos8 ssl]#openssl req -newkey rsa:2048 -nodes -keyout slave.key >
slave.csr
Generating a RSA private key
.................................+++++
...............................................+++++
writing new private key to 'slave.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:magedu
Organizational Unit Name (eg, section) []:opt
Common Name (eg, your name or your server's hostname) []:slave.magedu.org
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@centos8 ssl]#
[root@centos8 ssl]#openssl x509 -req -in slave.csr -CA cacert.pem -CAkey
cakey.pem --set_serial 02 > slave.crt
Signature ok
subject=C = CN, ST = beijing, L = beijing, O = magedu, OU = opt, CN =
slave.magedu.org
Getting CA Private Key
[root@centos8 ssl]#ls
cacert.pem cakey.pem master.crt master.csr master.key slave.crt slave.csr
slave.key
[mysqld]
log-bin
server_id=1
ssl
ssl-ca=/etc/my.cnf.d/ssl/cacert.pem
ssl-cert=/etc/my.cnf.d/ssl/master.crt
ssl-key=/etc/my.cnf.d/ssl/master.key
[root@centos8 ~]#chown -R mysql.mysql /etc/d/ssl/径
GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'192.168.8.%' IDENTIFIED BY 'magedu' REQUIRE SSL;
[root@centos8 ~]#mysql -urepluser -pmagedu -h192.168.100.8
ERROR 1045 (28000): Access denied for user 'repluser'@'192.168.100.18' (using
password: YES)
[root@centos8 ~]#mysql -urepluser -pmagedu -h192.168.100.8 --sslca=/etc/my.cnf.d/ssl/cacert.pem --ssl-cert=/etc/my.cnf.d/ssl/slave.crt --sslkey=/etc/my.cnf.d/ssl/slave.key
MariaDB [(none)]>
[root@centos8 ~]#chown -R mysql.mysql /etc/my.cnf.d/ssl/
mysql>
CHANGE MASTER TO
MASTER_HOST='MASTERIP',
MASTER_USER='repluser',
MASTER_PASSWORD='magedu',
MASTER_LOG_FILE='mariadb-bin.000001',
MASTER_LOG_POS=245,
MASTER_SSL=1,
MASTER_SSL_CA = '/etc/my.cnf.d/ssl/cacert.pem',
MASTER_SSL_CERT = '/etc/my.cnf.d/ssl/slave.crt',
MASTER_SSL_KEY = '/etc/my.cnf.d/ssl/slave.key';
PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }
RESET MASTER # #mysql 不支持
RESET SLAVE
SHOW MASTER STATUS
SHOW BINARY LOGS
SHOW BINLOG EVENTS
SHOW SLAVE STATUS
SHOW PROCESSLIST
Seconds_Behind_Master:0
percona-toolkit
GTID复制:(global transaction id 全局事务标识符) MySQL5.6版本开始支持,GTID复制不像传统的复制方式(异步复制、半同步复制)需要找到binlog和POS点,只需知道master的IP、端口、账号、密码即可。开启GTID后,执行change master to master_auto_postion=1即可,它会自动寻找同步
gtid_mode #gtid模式
enforce_gtid_consistency #保证GTID安全的参数
vim /etc/my.cnf
server-id=1
log-bin=mysql-bin
gtid_mode=ON
enforce_gtid_consistency
mysql> grant replication slave on . to 'repluser'@'192.168.8.%' identified by
'P@ssw0rd!';
从服务器
vim /etc/my.cnf
server-id=2
gtid_mode=ON
enforce_gtid_consistency
mysql>CHANGE MASTER TO MASTER_HOST='192.168.8.100',
MASTER_USER='repluser',
MASTER_PASSWORD='P@ssw0rd!',
MASTER_PORT=3306,
MASTER_AUTO_POSITION=1;
mysql>start slave;
Master: MHA + semi repl
Slave: 重新复制
从库重新实现
虽然这也是一种解决方法,但是这个方案恢复时间比较慢,而且有时候从库也是承担一部分的查询操作的,不能贸然重建。
使用percona-toolkit工具辅助
PT工具包中包含pt-table-checksum和pt-table-sync两个工具,主要用于检测主从是否一致以及修复数据不一致情况。这种方案优点是修复速度快,不需要停止主从辅助,缺点是需要知识积累,需要时间去学习,去测试,特别是在生产环境,还是要小心使用
手动重建不一致的表
在从库发现某几张表与主库数据不一致,而这几张表数据量也比较大,手工比对数据不现实,并且重做整个库也比较慢,这个时候可以只重做这几张表来修复主从不一致这种方案缺点是在执行导入期间需要暂时停止从库复制,不过也是可以接受的
1、从库停止Slave复制
mysql>stop slave;
2、在主库上dump这三张表,并记录下同步的binlog和POS点
mysqldump -uroot -pmagedu -q --single-transaction --master-data=2
testdb A B C >/backup/A_B_C.sql
3、查看A_B_C.sql文件,找出记录的binlog和POS点
head A_B_C.sql
例如:MASTERLOGFILE='mysql-bin.888888', MASTERLOGPOS=66666666;
4、把A_B_C.sql拷贝到Slave机器上,并做Change master to指向新位置
mysql>start slave until MASTERLOGFILE='mysql-bin.888888',
MASTERLOGPOS=66666666;
#以上指令是为了保障其他表的数据不丢失,一直同步,直到同步完那个点结束,A,B,C表的数据在之前的备份已经生成了一份快照,只需要导入进入,然后开启同步即可
5、在Slave机器上导入A_B_C.sql
mysql -uroot -pmagedu testdb
mysql>set sql_log_bin=0;
mysql>source /backup/A_B_C.sql
6、导入完毕后,从库开启同步即可。
mysql>start slave;
数据库主要分为两大类:关系型数据库与 NoSQL 数据库。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v48o9mBA-1576071563171)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191203094333673.png)]
简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机) 上面,以达到分散单台设备负载的效果。
数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式。
水平切分于垂直切分相比,相对来说稍微复杂一些。因为要将同一个表中的不同数据拆分到不同的数据库中, 对于应用程序来说,拆分规则本身就较根据表名来拆分更为复杂,后期的数据维护也会更为复杂一些。
一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面,如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cPrjKiFs-1576071563171)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191203094632219.png)]
拆分数据就需要定义分片规则。关系型数据库是行列的二维模型,拆分的第一原则是找到拆分维度。比如: 从会员的角度来分析,商户订单交易类系统中查询会员某天某月某个订单,那么就需要按照会员结合日期来拆分, 不同的数据按照会员 ID 做分组,这样所有的数据查询 join 都会在单库内解决;如果从商户的角度来讲,要查询某 个商家某天所有的订单数,就需要按照商户 ID 做拆分;但是如果系统既想按会员拆分,又想按商家数据,则会有 一定的困难。如何找到合适的分片规则需要综合考虑衡量。
几种典型的分片规则包括:
按照用户 ID 求模,将数据分散到不同的数据库,具有相同数据用户的数据都被分散到一个库中
按照日期,将不同月甚至日的数据分散到不同的库中
按照某个特定的字段求摸,或者根据特定范围段分散到不同的库中
拆分规则抽象好,join 操作基本可以数据库做
不存在单库大数据,高并发的性能瓶颈
应用端改造较少
提高了系统的稳定性跟负载能力
拆分规则难以抽象
分片事务一致性难以解决
数据多次扩展难度跟维护量极大
跨库 join 性能较差
引入分布式事务的问题
跨节点 Join 的问题
跨节点合并排序分页问题
多数据源管理问题
A. 客户端模式,在每个应用程序模块中配置管理自己需要的一个(或者多个)数据源,直接访问各个数据库, 在模块内完成数据的整合
B. 通过中间代理层来统一管理所有的数据源,后端数据库集群对前端应用程序透明; 可能 90%以上的人在面对上面这两种解决思路的时候都会倾向于选择第二种,尤其是系统不断变得庞大复杂 的时候。确实,这是一个非常正确的选择,虽然短期内需要付出的成本可能会相对更大一些,但是对整个系统的 扩展性来说,是非常有帮助的。
mysql-proxy:Oracle,https://downloads.mysql.com/archives/proxy/
Atlas:Qihoo,https://github.com/Qihoo360/Atlas/blob/master/README_ZH.md
dbproxy:美团,https://github.com/Meituan-Dianping/DBProxy
Cetus:网易乐得,https://github.com/Lede-Inc/cetus
Amoeba:https://sourceforge.net/projects/amoeba/
Cobar:阿里巴巴,Amoeba的升级版 https://github.com/alibaba/cobar
Mycat:基于Cobar, http://www.mycat.io/
ProxySQL:https://proxysql.com/
支持SQL92标准
遵守MySQL 原生协议,跨语言,跨平台,跨数据库的通用中间件代理
基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster集群
支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster
基于Nio实现,有效管理线程,高并发问题
支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数,支持跨库分页
支持单库内部任意join,支持跨库2表join,甚至基于caltlet的多表join
支持通过全局表,ER关系的分片策略,实现了高效的多表join查询
支持多租户方案
支持分布式事务(弱xa)
支持全局序列号,解决分布式下的主键生成问题
分片规则丰富,插件化开发,易于扩展
强大的web,命令行监控
支持前端作为mysq通用代理,后端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb 、巨杉
支持密码加密
支持服务降级
支持IP白名单
支持SQL黑名单、sql注入攻击拦截
支持分表(1.6)
集群基于ZooKeeper管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)
需要注意: 在生产环境中, Mycat节点最好使用双节点, 即双机热备环境, 防止Mycat这一层出现单点故障.
可以使用的高可用集群方式有:
Keepalived+Mycat+Mysql
Keepalived+LVS+Mycat+Mysql
Keepalived+Haproxy+Mycat+Mysq
yum -y install java
#确认安装成功
java -version
openjdk version "1.8.0_201"
OpenJDK Runtime Environment (build 1.8.0_201-b09)
OpenJDK 64-Bit Server VM (build 25.201-b09, mixed mode)
wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
mkdir /app
tar xf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /app
ls /app/mycat/
bin catlet conf lib logs version.txt
server.xml Mycat软件本身相关的配置文件,设置账号、参数等
schema.xml Mycat对应的物理数据库和数据库表的配置,读写分离、高可用、分布式策略定制、节点控制(数据库账号信息)
rule.xml Mycat分片(分库分表)规则配置文件,记录分片规则列表、使用方法等
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fvBp9O8B-1576071563172)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191129162623360.png)]
#配置环境变量
vim /etc/profile.d/mycat.sh
export PATH=/app/mycat/bin:$PATH
source /etc/profile.d/mycat.sh
#启动
mycat start
#查看日志,确定成功
cat /app/mycat/logs/wrapper.log
...省略...
INFO | jvm 1 | 2019/11/01 21:41:02 | MyCAT Server startup successfully. see
logs in logs/mycat.log
#连接mycat:
mysql -uroot -p123456 -h 127.0.0.1 -P8066
参数 | 说明 |
---|---|
user | 用户配置节点 |
name | 登录的用户名,也就是连接Mycat的用户名。 |
password | 登录的密码 |
schemas | 数据库名,这里会和schema.xml中的配置关联,多个用逗号分开,例如:db1,db2 |
privileges | 配置用户针对表的增删改查的权限 |
readOnly | mycat逻辑库所具有的权限。true为只读,false为读写都有,默认为false |
参数 | 说明 |
---|---|
schema | 数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应 |
dataNode | 分片信息,也就是分库相关配置 |
dataHost | 物理数据库,真正存储数据的数据库 |
属性 | 说明 |
---|---|
name | 逻辑数据库名,与server.xml中的schema对应 |
checkSQLschema | 数据库前缀相关设置,这里为false |
sqlMaxLimit | select 时默认的limit,避免查询全表 |
属性 | 说明 |
---|---|
name | 表名,物理数据库中表名 |
dataNode | 表存储到哪些节点,多个节点用逗号分隔。节点为下文dataNode设置的name |
primaryKey | 主键字段名,自动生成主键时需要设置 |
autoIncrement | 是否自增 |
rule | 分片规则名,具体规则下文rule详细介绍 |
属性 | 说明 |
---|---|
name | 节点名,与table中dataNode对应 |
datahost | 物理数据库名,与datahost中name对应 |
database | 物理数据库中数据库名 |
属性 | 说明 |
---|---|
name | 物理数据库名,与dataNode中dataHost对应 |
balance | 均衡负载的方式 |
writeType | 写入方式 |
dbType | 数据库类型 |
heartbeat | 心跳检测语句,注意语句结尾的分号要加 |
注意:
系统环境:
cat /etc/centos-release
CentOS Linux release 8.0.1905 (Core)
echo $PATH
/app/mycat/bin:/usr/share/Modules/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
服务器共三台
mycat-server 192.168.100.10
mysql-master 192.168.100.11
mysql-slave 192.168.100.12
systemctl stop firewalld
setenforce 0
yum -y install mariadb-server
#master上的my.cnf
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id = 1
log-bin
#slave上的my.cnf
[mysqld]
server-id = 2
[root@centos8 ~]#systemctl start mariadb
[root@centos8 ~]#mysql -uroot -p
MariaDB [(none)]>GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'192.168.100.12'
IDENTIFIED BY 'replpass';
mysql> FLUSH PRIVILEGES;
mysql> show master status;
+------------------+----------+--------------+------------------+---------------
----+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
Executed_Gtid_Set |
+------------------+----------+--------------+------------------+---------------
----+
|mariadb-bin.000001| 403 | | |
|
+------------------+----------+--------------+------------------+---------------
----+
1 row in set (0.00 sec)
mysql> CHANGE MASTER TO
-> MASTER_HOST='192.168.100.11',
-> MASTER_USER='repluser',
-> MASTER_PASSWORD='replpass',
-> MASTER_LOG_FILE='mariadb-bin.000001',
-> MASTER_LOG_POS=403;
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.100.11
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mariadb-bin.000001
Read_Master_Log_Pos: 439
Relay_Log_File: mariadb-relay-bin.000002
Relay_Log_Pos: 689
Relay_Master_Log_File: mariadb-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...省略..,
[root@centos8 ~]#yum -y install java mariadb
#确认安装成功
[root@centos8 ~]#java -version
openjdk version "1.8.0_201"
OpenJDK Runtime Environment (build 1.8.0_201-b09)
OpenJDK 64-Bit Server VM (build 25.201-b09, mixed mode)
#下载并安装
[root@centos8 ~]#wget http://dl.mycat.io/1.6.7.3/20190927161129/Mycat-server-
1.6.7.3-release-20190927161129-linux.tar.gz
[root@centos8 ~]#mkdir /app
[root@centos8 ~]#tar xvf Mycat-server-1.6.7.3-release-20190927161129-
linux.tar.gz -C /app
#配置环境变量
[root@centos8 ~]#vim /etc/profile.d/mycat.sh
PATH=/app/mycat/bin:$PATH
[root@centos8 ~]#source /etc/profile.d/mycat.sh
#查看端口
[root@centos8 ~]#ss -ntl
State Recv-Q Send-Q
Local Address:Port Peer Address:Port
LISTEN 0 128
0.0.0.0:22 0.0.0.0:*
LISTEN 0 128
[::]:22 [::]:*
*:*
#启动mycat
[root@centos8 ~]#mycat start
Starting Mycat-server...
[root@centos8 ~]#ss -ntlp
State Recv-Q Send-Q Local Address:Port
Peer Address:Port
LISTEN 0 128 0.0.0.0:22
0.0.0.0:* users:(("sshd",pid=791,fd=5))
LISTEN 0 1 127.0.0.1:32000
0.0.0.0:* users:(("java",pid=4640,fd=4))
LISTEN 0 128 [::]:22
[::]:* users:(("sshd",pid=791,fd=7))
LISTEN 0 50 *:1984
*:* users:
(("java",pid=4640,fd=57))
LISTEN 0 100 *:8066
*:* users:
(("java",pid=4640,fd=87))
LISTEN 0 50 *:43465
*:* users:(("java",pid=4640,fd=58))
LISTEN 0 100 *:9066
*:* users:
(("java",pid=4640,fd=83))
LISTEN 0 50 *:45259
*:* users:(("java",pid=4640,fd=56))
#查看日志,确定成功
[root@centos8 ~]#cat /app/mycat/logs/wrapper.log
#用默认密码123456来连接mycat:
[root@centos8 ~]#mysql -uroot -p123456 -h 127.0.0.1 -P8066
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.29-mycat-1.6-RELEASE-20161028204710 MyCat Server
(OpenCloundDB)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
vim /app/mycat/conf/server.xml
…省略…
#连接Mycat的用户名
magedu #连接Mycat的密码
TESTDB # 数据库名要和schema.xml相对应
- 这里使用的是root,密码为magedu,逻辑数据库为TESTDB,这些信息都可以自己随意定义,读写权限都有,没有针对表做任何特殊的权限。重点关注上面这段配置,其他默认即可。
- ###### 修改schema.xml实现读写分离策略
```bash
vim /app/mycat/conf/schema.xml
select user()
上面配置中,balance改为1,表示读写分离。
以上配置达到的效果就是192.168.8.11为主库,192.168.8.12为从库。
注意:要保证192.168.8.11和192.168.8.12机器能使用root/123456权限成功登录mysql数据库。同时,也一定要授权mycat机器能使用root/123456权限成功登录这两台机器的mysql数据库!!这很重要,否则会导致登录mycat后,对库和表操作失败!
[root@centos8 ~]#mysql -uroot -p
mysql> create database mycat;
mysql>GRANT ALL ON *.* TO 'root'@'192.168.100.10' IDENTIFIED BY '123456' WITH
GRANT OPTION;
mysql> flush privileges;
[root@centos8 ~]#mysql -uroot -pmagedu -h127.0.0.1 -P8066 -DTESTDB
mysql> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB | #只能看一个虚拟数据库
+----------+
mysql> use TESTDB;
mysql> create table t1(id int);
MySQL> select @@server_id;
在mysql中查看日志
主从服务器分别启用通用日志,查看读写分离
set global general_log=on;
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
general_log=ON
[root@centos8 ~]#systemctl restart mariadb
[root@centos8 ~]#tail -f /var/lib/mysql/centos8.log
cat <<EOF | tee /etc/yum.repos.d/proxysql.repo
[proxysql_repo]
name= ProxySQL YUM repository
baseurl=http://repo.proxysql.com/ProxySQL/proxysql-1.4.x/centos/$releasever
gpgcheck=1
gpgkey=http://repo.proxysql.com/ProxySQL/repo_pub_key
EOF
yum install proxysql
service proxysql start
mysql -uadmin -padmin -P6032 -h127.0.0.1
MySQL> show tables;
MySQL > select * from sqlite_master where name='mysql_servers'\G
MySQL > select * from mysql_servers;
MySQL > insert into mysql_servers(hostgroup_id,hostname,port)
values(10,'192.168.8.17',3306);
MySQL > insert into mysql_servers(hostgroup_id,hostname,port)
values(10,'192.168.8.27',3306);
MySQL > load mysql servers to runtime;
MySQL > save mysql servers to disk;
#在master上执行
MySQL> grant replication client on *.* to monitor@'192.168.8.%' identified
by 'magedu';
#ProxySQL上配置监控
MySQL [(none)]> set mysql-monitor_username='monitor';
MySQL [(none)]> set mysql-monitor_password='magedu';
#加载到RUNTIME,并保存到disk
MySQL [(none)]> load mysql variables to runtime;
MySQL [(none)]> save mysql variables to disk;
#查看监控连接是否正常的 (对connect指标的监控),如果connect_error的结果为NULL则表示正常 My
SQL> select * from mysql_server_connect_log;
#查看监控心跳信息 (对ping指标的监控):
MySQL> select * from mysql_server_ping_log;
writer_hostgroup,reader_hostgroup,comment, 指定写组的id为10,读组的id为20
MySQL> insert into mysql_replication_hostgroups values(10,20,"test");
将mysql_replication_hostgroups表的修改加载到RUNTIME生效
MySQL> load mysql servers to runtime;
MySQL> save mysql servers to disk;
#Monitor模块监控后端的read_only值,按照read_only的值将节点自动移动到读/写组
MySQL> select hostgroup_id,hostname,port,status,weight from mysql_servers;
±-------------±-------------±-----±-------±-------+
| hostgroup_id | hostname | port | status | weight |
±-------------±-------------±-----±-------±-------+
| 10 | 192.168.8.17 | 3306 | ONLINE | 1 |
| 20 | 192.168.8.27 | 3306 | ONLINE | 1 |
- ##### 配置访问数据库的SQL 用户
```mysql
#在master节点上创建访问用户
MySQL> grant all on *.* to sqluser@'192.168.8.%' identified by 'magedu';
#在ProxySQL配置,将用户sqluser添加到mysql_users表中, default_hostgroup默认组设置为写组10,当读写分离的路由规则不符合时,会访问默认组的数据库
MySQL> insert into mysql_users(username,password,default_hostgroup)
values('sqluser','magedu',10);
MySQL> load mysql users to runtime;
MySQL> save mysql users to disk;
#使用sqluser用户测试是否能路由到默认的10写组实现读、写数据
mysql -usqluser -pmagedu -P6033 -h127.0.0.1 -e 'select @@server_id'
mysql -usqluser -pmagedu -P6033 -h127.0.0.1 -e 'create database testdb'
mysql -usqluser -pmagedu testdb -P6033 -h127.0.0.1 -e 'create table t(id
int)'
MySQL> insert into mysql_query_rules
(rule_id,active,match_digest,destination_hostgroup,apply)VALUES
(1,1,'^SELECT.*FOR UPDATE$',10,1),(2,1,'^SELECT',20,1);
MySQL> load mysql query rules to runtime;
MySQL> save mysql query rules to disk;
#注意:因ProxySQL根据rule_id顺序进行规则匹配,select ... for update规则的rule_id必须要小于普通的select规则的rule_id
#读操作是否路由给20的读组
mysql -usqluser -pmagedu -P6033 -h127.0.0.1 -e 'select @@server_id'
#测试写操作,以事务方式进行测试
mysql -usqluser -pmagedu -P6033 -h127.0.0.1 \
-e 'start transaction;select @@server_id;commit;select @@server_id'
mysql -usqluser -pmagedu -P6033 -h127.0.0.1 -e 'insert testdb.t values (1)'
mysql -usqluser -pmagedu -P6033 -h127.0.0.1 -e 'select id from testdb.t'
#路由的信息:查询stats库中的stats_mysql_query_digest表
MySQL > SELECT hostgroup hg,sum_time, count_star, digest_text FROM
stats_mysql_query_digest ORDER BY sum_time DESC;
#测试读操作是否路由给20的读组
mysql -usqluser -pmagedu -P6033 -h127.0.0.1 -e 'select @@server_id'
#测试写操作,以事务方式进行测试
mysql -usqluser -pmagedu -P6033 -h127.0.0.1 \
-e 'start transaction;select @@server_id;commit;select @@server_id'
mysql -usqluser -pmagedu -P6033 -h127.0.0.1 -e 'insert testdb.t values (1)'
mysql -usqluser -pmagedu -P6033 -h127.0.0.1 -e 'select id from testdb.t'
#路由的信息:查询stats库中的stats_mysql_query_digest表
MySQL > SELECT hostgroup hg,sum_time, count_star, digest_text FROM
stats_mysql_query_digest ORDER BY sum_time DESC;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KN8hDz4t-1576071563173)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191203102454149.png)]
MMM: Multi-Master Replication Manager for MySQL,Mysql主主复制管理器是一套灵活的脚本程序,基于perl实现,用来对mysql replication进行监控和故障迁移,并能管理mysql MasterMaster复制的配置(同一时间只有一个节点是可写的)
官网: http://www.mysql-mmm.org
https://code.google.com/archive/p/mysql-master-master/downloads
MHA:Master High Availability,对主节点进行监控,可实现自动故障转移至其它从节点;通过提升某一从节点为新的主节点,基于主从复制实现,还需要客户端配合实现,目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库,出于机器成本的考虑,淘宝进行了改造,目前淘宝TMHA已经支持一主一从
官网:https://code.google.com/archive/p/mysql-master-ha/
https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads
通过wsrep协议在全局实现复制;任何一节点都可读写,不需要主从复制,实现多主读写
GR(Group Replication):MySQL官方提供的组复制技术(MySQL 5.7.17引入的技术),基于原生复制技术Paxos算法,实现了多主更新,复制组由多个server成员构成,组中的每个server可独立地执行事务,但所有读写事务只在冲突检测成功后才会提交
这3个节点互相通信,每当有事件发生,都会向其他节点传播该事件,然后协商,如果大多数节点都同意这次的事件,那么该事件将通过,否则该事件将失败或回滚。这些节点可以是单主模型的(single-primary),也可以是多主模型的(multi-primary)。单主模型只有一个主节点可以接受写操作,主节点故障时可以自动选举主节点。多主模型下,所有节点都可以接受写操作,所以没有master-slave的概念。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9hbsJyiF-1576071563174)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191123175541254.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vjk6r293-1576071563175)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191123175625883.png)]
masterha_check_ssh 检查MHA的SSH配置状况
masterha_check_repl 检查MySQL复制状况
masterha_manger 启动MHA
masterha_check_status 检测当前MHA运行状态
masterha_master_monitor 检测master是否宕机
masterha_master_switch 故障转移(自动或手动)
masterha_conf_host 添加或删除配置的server信息
save_binary_logs 保存和复制master的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的slave
filter_mysqlbinlog 去除不必要的ROLLBACK事件(MHA已不再使用此工具)
purge_relay_logs 清除中继日志(不会阻塞SQL线程)
注意:为了尽可能的减少主库硬件损坏宕机造成的数据丢失,因此在配置MHA的同时建议配置成MySQL 5.5的半同步复制
secondary_check_script: 通过多条网络路由检测master的可用性
master_ip_ailover_script: 更新Application使用的masterip
shutdown_script: 强制关闭master节点
report_script: 发送报告init_conf_load_script: 加载初始配置参数
master_ip_online_change_script: 更新master节点ip地址
mha4mysql-manager
mha4mysql-node
mha4mysql-node
vim /etc/mastermha/app1.cnf
[server default]
user=mhauser
password=magedu
manager_workdir=/data/mastermha/app1/
manager_log=/data/mastermha/app1/manager.log
remote_workdir=/data/mastermha/app1/
ssh_user=root
repl_user=repluser
repl_password=magedu
ping_interval=1
[server1]
hostname=192.168.8.17
candidate_master=1
[server2]
hostname=192.168.8.27
candidate_master=1
[server3]
hostname=192.168.8.37
vim /etc/my.cnf
[mysqld]
log-bin
server_id=1
skip_name_resolve=1
mysql>show master logs
mysql>grant replication slave on *.* to repluser@'192.168.8.%' identified by
‘magedu';
mysql>grant all on *.* to mhauser@'192.168.8.%’identified by‘magedu';
vim /etc/my.cnf
[mysqld]
server_id=2 #不同节点此值各不相同
log-bin
read_only
relay_log_purge=0 #中继日志不删除,默认是删除
skip_name_resolve=1
mysql>CHANGE MASTER TO MASTER_HOST=‘MASTER_IP', MASTER_USER='repluser',
MASTER_PASSWORD=‘magedu', MASTER_LOG_FILE='mariadb-bin.000001',
MASTER_LOG_POS=245;
masterha_check_ssh --conf=/etc/mastermha/app1.cnf
masterha_check_repl --conf=/etc/mastermha/app1.cnf
masterha_manager --conf=/etc/mastermha/app1.cnf #一次性任务,执行后一致显示在前段,终端不能关闭
/data/mastermha/app1/manager.log
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NH2fA12F-1576071563176)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191123182240939.png)]
http://galeracluster.com/documentation-webpages/galera-documentation.pdf
http://galeracluster.com/documentation-webpages/index.html
https://mariadb.com/kb/en/mariadb/getting-started-with-mariadb-galera-cluster/
https://mirrors.tuna.tsinghua.edu.cn/percona/release/$releasever/RPMS/$basearch
https://mirrors.tuna.tsinghua.edu.cn/mariadb/mariadb-5.5.X/yum/centos7-amd64/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Woeaft6o-1576071563176)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191203103624974.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JxhHksED-1576071563177)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191203103736850.png)]
open:节点启动成功,尝试连接到集群时的状态
primary:节点已处于集群中,在新节点加入并选取donor进行数据同步时的状态
joiner:节点处于等待接收同步文件时的状态
joined:节点完成数据同步工作,尝试保持和集群进度一致时的状态
synced:节点正常提供服务时的状态,表示已经同步完成并和集群进度保持一致
donor:节点处于为新加入的节点提供全量数据时的状态
pxc1:10.0.0.7
pxc1:10.0.0.17
pxc1:10.0.0.27
pxc4:10.0.0.37
[root@pxc1 ~]#cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
#关闭防火墙和SELinux,保证时间同步
#注意:如果已经安装MySQL,必须卸载
#使用清华大学yum源,官方源太慢了
[root@pxc1 ~]#vim /etc/yum.repos.d/pxc.repo
[percona]
name=percona_repo
baseurl =
https://mirrors.tuna.tsinghua.edu.cn/percona/release/$releasever/RPMS/$basearch
enabled = 1
gpgcheck = 0
[root@pxc1 ~]#scp /etc/yum.repos.d/pxc.repo 10.0.0.17:/etc/yum.repos.d
[root@pxc1 ~]#scp /etc/yum.repos.d/pxc.repo 10.0.0.27:/etc/yum.repos.d
#在三个节点都安装好PXC 5.7
[root@pxc1 ~]#yum install Percona-XtraDB-Cluster-57 -y
[root@pxc2 ~]#yum install Percona-XtraDB-Cluster-57 -y
[root@pxc3 ~]#yum install Percona-XtraDB-Cluster-57 -y
/etc/my.cnf为主配置文件,当前版本中,其余的配置文件都放在/etc/percona-xtradb-cluster.conf.d目录里,包括mysqld.cnf,mysqld_safe.cnf,wsrep.cnf 三个文件
#主配置文件不需要修改
[root@pxc1 ~]#cat /etc/my.cnf
# The Percona XtraDB Cluster 5.7 configuration file.
...省略...
!includedir /etc/my.cnf.d/
!includedir /etc/percona-xtradb-cluster.conf.d/
[root@pxc1 ~]#ls /etc/my.cnf.d/
[root@pxc1 ~]#ls /etc/percona-xtradb-cluster.conf.d/
mysqld.cnf mysqld_safe.cnf wsrep.cnf
#下面配置文件不需要修改
[root@pxc1 ~]#cat /etc/percona-xtradb-cluster.conf.d/mysqld.cnf
...省略...
[client]
socket=/var/lib/mysql/mysql.sock
[mysqld]
server-id=1 #建议各个节点不同
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
log-bin #建议启用,非必须项
log_slave_updates
expire_logs_days=7
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
#下面配置文件不需要修改
[root@pxc1 ~]#cat /etc/percona-xtradb-cluster.conf.d/mysqld_safe.cnf
...省略...
[mysqld_safe]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/lib/mysql/mysql.sock
nice = 0
#PXC的配置文件必须修改
[root@pxc1 ~]#vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[root@pxc1 ~]#grep -Ev "^#|^$" /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[mysqld]
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
wsrep_cluster_address=gcomm://10.0.0.7,10.0.0.17,10.0.0.27 #三个节点的IP
binlog_format=ROW
default_storage_engine=InnoDB
wsrep_slave_threads= 8
wsrep_log_conflicts
innodb_autoinc_lock_mode=2
wsrep_node_address=10.0.0.7 #各个节点,指定自已的IP
wsrep_cluster_name=pxc-cluster
wsrep_node_name=pxc-cluster-node-1 #各个节点,指定自已节点名称
pxc_strict_mode=ENFORCING
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth="sstuser:s3cretPass" #取消本行注释
[root@pxc2 ~]#grep -Ev "^#|^$" /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[mysqld]
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
wsrep_cluster_address=gcomm://10.0.0.7,10.0.0.17,10.0.0.27
binlog_format=ROW
default_storage_engine=InnoDB
wsrep_slave_threads= 8
wsrep_log_conflicts
innodb_autoinc_lock_mode=2 #各个节点,指定自已的IP
wsrep_node_address=10.0.0.17
wsrep_cluster_name=pxc-cluster
wsrep_node_name=pxc-cluster-node-2 #各个节点,指定自已节点名称
pxc_strict_mode=ENFORCING
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth="sstuser:s3cretPass" #取消本行注释
[root@pxc3 ~]#grep -Ev "^#|^$" /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[mysqld]
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
wsrep_cluster_address=gcomm://10.0.0.7,10.0.0.17,10.0.0.27
binlog_format=ROW
default_storage_engine=InnoDB
wsrep_slave_threads= 8
wsrep_log_conflicts
innodb_autoinc_lock_mode=2
wsrep_node_address=10.0.0.27 #各个节点,指定自已的IP
wsrep_cluster_name=pxc-cluster
wsrep_node_name=pxc-cluster-node-3 #各个节点,指定自已的IP
pxc_strict_mode=ENFORCING
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth="sstuser:s3cretPass" #取消本行注释
#注意:尽管Galera Cluster不再需要通过binlog的形式进行同步,但还是建议在配置文件中开启二进制日志功能,原因是后期如果有新节点需要加入,老节点通过SST全量传输的方式向新节点传输数据,很可能会拖垮集群性能,所以让新节点先通过binlog方式完成同步后再加入集群会是一种更好的选择
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p5jTVOV7-1576071563178)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191203104140719.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kOw9EeG4-1576071563178)(%E6%88%AA%E5%9B%BE/2019%E5%B9%B411%E6%9C%8821%E6%97%A5/image-20191203104204907.png)]
root@pxc1 ~]#ss -ntul
Netid State Recv-Q Send-Q Local Address:Port
Peer Address:Port
udp UNCONN 0 0 127.0.0.1:323
*:*
udp UNCONN 0 0 ::1:323
:::*
tcp LISTEN 0 128 *:22
*:*
tcp LISTEN 0 100 127.0.0.1:25
*:*
tcp LISTEN 0 128 :::22
:::*
tcp LISTEN 0 100 ::1:25
:::*
#启动第一人节点
[root@pxc1 ~]#systemctl start [email protected]
[root@pxc1 ~]#ss -ntul
Netid State Recv-Q Send-Q Local Address:Port Peer
Address:Port
udp UNCONN 0 0 127.0.0.1:323
*:*
udp UNCONN 0 0 ::1:323
:::*
tcp LISTEN 0 128 *:22
*:*
tcp LISTEN 0 128 *:4567
*:*
tcp LISTEN 0 100 127.0.0.1:25
*:*
tcp LISTEN 0 80 :::3306
:::*
tcp LISTEN 0 128 :::22
:::*
tcp LISTEN 0 100 ::1:25
:::*
#查看root密码
[root@pxc1 ~]#grep "temporary password" /var/log/mysqld.log
2019-11-30T02:53:54.292659Z 1 [Note] A temporary password is generated for
root@localhost: =tWFP0oRJl8t
[root@pxc1 ~]#mysql -uroot -p'=tWFP0oRJl8t'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.7.27-30-57-log
Copyright (c) 2009-2019 Percona LLC and/or its affiliates
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
#修改root密码
mysql> alter user 'root'@'localhost' identified by 'magedu';
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE USER 'sstuser'@'localhost' IDENTIFIED BY 's3cretPass';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO
-> 'sstuser'@'localhost';
Query OK, 0 rows affected (0.01 sec)
#查看相关变量
mysql> SHOW VARIABLES LIKE 'wsrep%'\G
*************************** 1. row ***************************
Variable_name: wsrep_OSU_method
Value: TOI
*************************** 2. row ***************************
Variable_name: wsrep_RSU_commit_timeout
Value: 5000
*************************** 3. row ***************************
Variable_name: wsrep_auto_increment_control
Value: ON
*************************** 4. row ***************************
Variable_name: wsrep_causal_reads
Value: OFF
*************************** 5. row ***************************
Variable_name: wsrep_certification_rules
Value: strict
*************************** 6. row ***************************
Variable_name: wsrep_certify_nonPK
Value: ON
*************************** 7. row ***************************
Variable_name: wsrep_cluster_address
Value: gcomm://10.0.0.7,10.0.0.17,10.0.0.27
*************************** 8. row ***************************
Variable_name: wsrep_cluster_name
Value: pxc-cluster
*************************** 9. row ***************************
Variable_name: wsrep_convert_LOCK_to_trx
Value: OFF
*************************** 10. row ***************************
Variable_name: wsrep_data_home_dir
Value: /var/lib/mysql/
*************************** 11. row ***************************Variable_name: wsrep_dbug_option
Value:
*************************** 12. row ***************************
Variable_name: wsrep_debug
Value: OFF
*************************** 13. row ***************************
Variable_name: wsrep_desync
Value: OFF
*************************** 14. row ***************************
Variable_name: wsrep_dirty_reads
Value: OFF
*************************** 15. row ***************************
Variable_name: wsrep_drupal_282555_workaround
Value: OFF
*************************** 16. row ***************************
Variable_name: wsrep_forced_binlog_format
Value: NONE
*************************** 17. row ***************************
Variable_name: wsrep_load_data_splitting
Value: ON
*************************** 18. row ***************************
Variable_name: wsrep_log_conflicts
Value: ON
*************************** 19. row ***************************
Variable_name: wsrep_max_ws_rows
Value: 0
*************************** 20. row ***************************
Variable_name: wsrep_max_ws_size
Value: 2147483647
*************************** 21. row ***************************
Variable_name: wsrep_node_address
Value: 10.0.0.7
*************************** 22. row ***************************
Variable_name: wsrep_node_incoming_address
Value: AUTO
*************************** 23. row ***************************
Variable_name: wsrep_node_name
Value: pxc-cluster-node-1
*************************** 24. row ***************************
Variable_name: wsrep_notify_cmd
Value:
*************************** 25. row ***************************
Variable_name: wsrep_on
Value: ON
*************************** 26. row ***************************
Variable_name: wsrep_preordered
Value: OFF
*************************** 27. row ***************************
Variable_name: wsrep_provider
Value: /usr/lib64/galera3/libgalera_smm.so
*************************** 28. row ***************************
Variable_name: wsrep_provider_optionsValue: base_dir = /var/lib/mysql/; base_host = 10.0.0.7; base_port =
4567; cert.log_conflicts = no; cert.optimistic_pa = yes; debug = no;
evs.auto_evict = 0; evs.causal_keepalive_period = PT1S; evs.debug_log_mask =
0x1; evs.delay_margin = PT1S; evs.delayed_keep_period = PT30S;
evs.inactive_check_period = PT0.5S; evs.inactive_timeout = PT15S;
evs.info_log_mask = 0; evs.install_timeout = PT7.5S; evs.join_retrans_period =
PT1S; evs.keepalive_period = PT1S; evs.max_install_timeouts = 3; evs.send_window
= 10; evs.stats_report_period = PT1M; evs.suspect_timeout = PT5S;
evs.use_aggregate = true; evs.user_send_window = 4; evs.version = 0;
evs.view_forget_timeout = P1D; gcache.dir = /var/lib/mysql/;
gcache.freeze_purge_at_seqno = -1; gcache.keep_pages_count = 0;
gcache.keep_pages_size = 0; gcache.mem_size = 0; gcache.name =
/var/lib/mysql//galera.cache; gcache.page_size = 128M; gcache.recover = no;
gcache.size = 128M; gcomm.thread_prio = ; gcs.fc_debug = 0; gcs.fc_factor = 1;
gcs.fc_limit = 100; gcs.fc_master_slave = no; gcs
*************************** 29. row ***************************
Variable_name: wsrep_recover
Value: OFF
*************************** 30. row ***************************
Variable_name: wsrep_reject_queries
Value: NONE
*************************** 31. row ***************************
Variable_name: wsrep_replicate_myisam
Value: OFF
*************************** 32. row ***************************
Variable_name: wsrep_restart_slave
Value: OFF
*************************** 33. row ***************************
Variable_name: wsrep_retry_autocommit
Value: 1
*************************** 34. row ***************************
Variable_name: wsrep_slave_FK_checks
Value: ON
*************************** 35. row ***************************
Variable_name: wsrep_slave_UK_checks
Value: OFF
*************************** 36. row ***************************
Variable_name: wsrep_slave_threads
Value: 8
*************************** 37. row ***************************
Variable_name: wsrep_sst_auth
Value: ********
*************************** 38. row ***************************
Variable_name: wsrep_sst_donor
Value:
*************************** 39. row ***************************
Variable_name: wsrep_sst_donor_rejects_queries
Value: OFF
*************************** 40. row ***************************
Variable_name: wsrep_sst_method
Value: xtrabackup-v2
*************************** 41. row ***************************
Variable_name: wsrep_sst_receive_address
Value: AUTO
*************************** 42. row ***************************
Variable_name: wsrep_start_position
Value: 00000000-0000-0000-0000-000000000000:-1
*************************** 43. row ***************************Variable_name: wsrep_sync_wait
Value: 0
43 rows in set (0.01 sec)
#查看相关状态变量
mysql> SHOW STATUS LIKE 'wsrep%'\G
*************************** 1. row ***************************
Variable_name: wsrep_local_state_uuid
Value: aad2c02e-131c-11ea-9294-b2e80a6c08c4
*************************** 2. row ***************************
Variable_name: wsrep_protocol_version
Value: 9
*************************** 3. row ***************************
Variable_name: wsrep_last_applied
Value: 3
*************************** 4. row ***************************
Variable_name: wsrep_last_committed
Value: 3
*************************** 5. row ***************************
Variable_name: wsrep_replicated
Value: 3
*************************** 6. row ***************************
Variable_name: wsrep_replicated_bytes
Value: 760
*************************** 7. row ***************************
Variable_name: wsrep_repl_keys
Value: 3
*************************** 8. row ***************************
Variable_name: wsrep_repl_keys_bytes
Value: 96
*************************** 9. row ***************************
Variable_name: wsrep_repl_data_bytes
Value: 465
*************************** 10. row ***************************
Variable_name: wsrep_repl_other_bytes
Value: 0
*************************** 11. row ***************************
Variable_name: wsrep_received
Value: 2
*************************** 12. row ***************************
Variable_name: wsrep_received_bytes
Value: 150
*************************** 13. row ***************************
Variable_name: wsrep_local_commits
Value: 0
*************************** 14. row ***************************
Variable_name: wsrep_local_cert_failures
Value: 0
*************************** 15. row ***************************
Variable_name: wsrep_local_replays
Value: 0
*************************** 16. row ***************************
Variable_name: wsrep_local_send_queue
Value: 0
*************************** 17. row ***************************
Variable_name: wsrep_local_send_queue_max
Value: 1
*************************** 18. row ***************************Variable_name: wsrep_local_send_queue_min
Value: 0
*************************** 19. row ***************************
Variable_name: wsrep_local_send_queue_avg
Value: 0.000000
*************************** 20. row ***************************
Variable_name: wsrep_local_recv_queue
Value: 0
*************************** 21. row ***************************
Variable_name: wsrep_local_recv_queue_max
Value: 2
*************************** 22. row ***************************
Variable_name: wsrep_local_recv_queue_min
Value: 0
*************************** 23. row ***************************
Variable_name: wsrep_local_recv_queue_avg
Value: 0.500000
*************************** 24. row ***************************
Variable_name: wsrep_local_cached_downto
Value: 1
*************************** 25. row ***************************
Variable_name: wsrep_flow_control_paused_ns
Value: 0
*************************** 26. row ***************************
Variable_name: wsrep_flow_control_paused
Value: 0.000000
*************************** 27. row ***************************
Variable_name: wsrep_flow_control_sent
Value: 0
*************************** 28. row ***************************
Variable_name: wsrep_flow_control_recv
Value: 0
*************************** 29. row ***************************
Variable_name: wsrep_flow_control_interval
Value: [ 100, 100 ]
*************************** 30. row ***************************
Variable_name: wsrep_flow_control_interval_low
Value: 100
*************************** 31. row ***************************
Variable_name: wsrep_flow_control_interval_high
Value: 100
*************************** 32. row ***************************
Variable_name: wsrep_flow_control_status
Value: OFF
*************************** 33. row ***************************
Variable_name: wsrep_cert_deps_distance
Value: 1.000000
*************************** 34. row ***************************
Variable_name: wsrep_apply_oooe
Value: 0.000000
*************************** 35. row ***************************
Variable_name: wsrep_apply_oool
Value: 0.000000
*************************** 36. row ***************************
Variable_name: wsrep_apply_window
Value: 1.000000
*************************** 37. row ***************************
Variable_name: wsrep_commit_oooeValue: 0.000000
*************************** 38. row ***************************
Variable_name: wsrep_commit_oool
Value: 0.000000
*************************** 39. row ***************************
Variable_name: wsrep_commit_window
Value: 1.000000
*************************** 40. row ***************************
Variable_name: wsrep_local_state
Value: 4
*************************** 41. row ***************************
Variable_name: wsrep_local_state_comment
Value: Synced
*************************** 42. row ***************************
Variable_name: wsrep_cert_index_size
Value: 1
*************************** 43. row ***************************
Variable_name: wsrep_cert_bucket_count
Value: 22
*************************** 44. row ***************************
Variable_name: wsrep_gcache_pool_size
Value: 2200
*************************** 45. row ***************************
Variable_name: wsrep_causal_reads
Value: 0
*************************** 46. row ***************************
Variable_name: wsrep_cert_interval
Value: 0.000000
*************************** 47. row ***************************
Variable_name: wsrep_open_transactions
Value: 0
*************************** 48. row ***************************
Variable_name: wsrep_open_connections
Value: 0
*************************** 49. row ***************************
Variable_name: wsrep_ist_receive_status
Value:
*************************** 50. row ***************************
Variable_name: wsrep_ist_receive_seqno_start
Value: 0
*************************** 51. row ***************************
Variable_name: wsrep_ist_receive_seqno_current
Value: 0
*************************** 52. row ***************************
Variable_name: wsrep_ist_receive_seqno_end
Value: 0
*************************** 53. row ***************************
Variable_name: wsrep_incoming_addresses
Value: 10.0.0.7:3306
*************************** 54. row ***************************
Variable_name: wsrep_cluster_weight
Value: 1
*************************** 55. row ***************************
Variable_name: wsrep_desync_count
Value: 0
*************************** 56. row ***************************
Variable_name: wsrep_evs_delayed
Value:*************************** 57. row ***************************
Variable_name: wsrep_evs_evict_list
Value:
*************************** 58. row ***************************
Variable_name: wsrep_evs_repl_latency
Value: 0/0/0/0/0
*************************** 59. row ***************************
Variable_name: wsrep_evs_state
Value: OPERATIONAL
*************************** 60. row ***************************
Variable_name: wsrep_gcomm_uuid
Value: aad1f935-131c-11ea-910a-ce3ee95c675e
*************************** 61. row ***************************
Variable_name: wsrep_cluster_conf_id
Value: 1
*************************** 62. row ***************************
Variable_name: wsrep_cluster_size
Value: 1
*************************** 63. row ***************************
Variable_name: wsrep_cluster_state_uuid
Value: aad2c02e-131c-11ea-9294-b2e80a6c08c4
*************************** 64. row ***************************
Variable_name: wsrep_cluster_status
Value: Primary
*************************** 65. row ***************************
Variable_name: wsrep_connected
Value: ON
*************************** 66. row ***************************
Variable_name: wsrep_local_bf_aborts
Value: 0
*************************** 67. row ***************************
Variable_name: wsrep_local_index
Value: 0
*************************** 68. row ***************************
Variable_name: wsrep_provider_name
Value: Galera
*************************** 69. row ***************************
Variable_name: wsrep_provider_vendor
Value: Codership Oy
*************************** 70. row ***************************
Variable_name: wsrep_provider_version
Value: 3.39(rb3295e6)
*************************** 71. row ***************************
Variable_name: wsrep_ready
Value: ON
71 rows in set (0.00 sec)
#重点关注下面内容
mysql> show status like 'wsrep%';
+----------------------------+--------------------------------------+
| Variable_name | Value |
+----------------------------+--------------------------------------+
| wsrep_local_state_uuid | aad2c02e-131c-11ea-9294-b2e80a6c08c4 |
| ... | ... |
| wsrep_local_state | 4 |
| wsrep_local_state_comment | Synced |
| ... | ... |
| wsrep_cluster_size | 1 |
| wsrep_cluster_status | Primary |
| wsrep_connected | ON |
| ... | ... |
| wsrep_ready | ON |
+----------------------------+--------------------------------------+
[root@pxc2 ~]#ss -ntul
Netid State Recv-Q Send-Q Local Address:Port Peer
Address:Port
udp UNCONN 0 0 127.0.0.1:323
*:*
udp UNCONN 0 0 ::1:323
:::*
tcp LISTEN 0 128 *:22
*:*
tcp LISTEN 0 100 127.0.0.1:25
*:*
tcp LISTEN 0 128 :::22
:::*
tcp LISTEN 0 100 ::1:25
:::*
[root@pxc2 ~]#systemctl start mysql
[root@pxc2 ~]#ss -ntulp
Netid State Recv-Q Send-Q Local Address:Port Peer
Address:Port
udp UNCONN 0 0 127.0.0.1:323
*:* users:(("chronyd",pid=6289,fd=1))
udp UNCONN 0 0 ::1:323
:::* users:(("chronyd",pid=6289,fd=2))
tcp LISTEN 0 128 *:22
*:* users:(("sshd",pid=6617,fd=3))
tcp LISTEN 0 128 *:4567
*:* users:(("mysqld",pid=7754,fd=11))
tcp LISTEN 0 100 127.0.0.1:25
*:* users:(("master",pid=6752,fd=13))
tcp LISTEN 0 80 :::3306
:::* users:(("mysqld",pid=7754,fd=34))
tcp LISTEN 0 128 :::22
:::* users:(("sshd",pid=6617,fd=4))
tcp LISTEN 0 100 ::1:25
:::* users:(("master",pid=6752,fd=14))
[root@pxc3 ~]#systemctl start mysql
#在任意节点,查看集群状态
[root@pxc1 ~]#mysql -uroot -pmagedu
mysql> SHOW VARIABLES LIKE 'wsrep_node_name';
+-----------------+--------------------+
| Variable_name | Value |
+-----------------+--------------------+
| wsrep_node_name | pxc-cluster-node-1 |
+-----------------+--------------------+
1 row in set (0.00 sec)
mysql> SHOW VARIABLES LIKE 'wsrep_node_address';
+--------------------+----------+
| Variable_name | Value |
+--------------------+----------+
| wsrep_node_address | 10.0.0.7 |
+--------------------+----------+
1 row in set (0.01 sec)
mysql> SHOW VARIABLES LIKE 'wsrep_on';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wsrep_on | ON |
+---------------+-------+
1 row in set (0.00 sec)
mysql> SHOW STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 3 |
+--------------------+-------+
1 row in set (0.01 sec)
#在任意节点查看数据库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
#在任意节点创建数据库
mysql> create database testdb1;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb1 |
+--------------------+
5 rows in set (0.00 sec)
mysql>
#在任意其它节点验证数据是否同步
[root@pxc2 ~]#mysql -uroot -pmagedu
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb1 |
+--------------------+
5 rows in set (0.01 sec)
#利用Xshell软件,同时在三个节点数据库,在其中一个节点成功
mysql> create database testdb2;
Query OK, 1 row affected (0.01 sec)
#在其它节点都提示失败
mysql> create database testdb2;
ERROR 1007 (HY000): Can't create database 'testdb2'; database exists
一个节点加入到Galera集群有两种情况:新节点加入集群、暂时离组的成员再次加入集群
新节点加入集群时,需要从当前集群中选择一个Donor节点来同步数据,也就是所谓的
state_snapshot_tranfer(SST)过程。SST同步数据的方式由选项wsrep_sst_method决定,一般选择的是xtrabackup。
必须注意,新节点加入Galera时,会删除新节点上所有已有数据,再通过xtrabackup(假设使用的是该方式)从Donor处完整备份所有数据进行恢复。所以,如果数据量很大,新节点加入过程会很慢。而且,在一个新节点成为Synced状态之前,不要同时加入其它新节点,否则很容易将集群压垮。
如果是这种情况,可以考虑使用wsrep_sst_method=rsync来做增量同步,既然是增量同步,最好保证新节点上已经有一部分数据基础,否则和全量同步没什么区别,且这样会对Donor节点加上全局read only锁。
如果旧节点加入Galera集群,说明这个节点在之前已经在Galera集群中呆过,有一部分数据基础,缺少的只是它离开集群时的数据。这时加入集群时,会采用IST(incremental snapshot transfer)传输机制,即使用增量传输。
但注意,这部分增量传输的数据源是Donor上缓存在GCache文件中的,这个文件有大小限制,如果缺失的数据范围超过已缓存的内容,则自动转为SST传输。如果旧节点上的数据和Donor上的数据不匹配(例如这个节点离组后人为修改了一点数据),则自动转为SST传输。
#在PXC集群中再加一台新的主机PXC4:10.0.0.37
[root@pxc4 ~]#yum install Percona-XtraDB-Cluster-57 -y
[root@pxc4 ~]#vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[root@pxc4 ~]#grep -Ev "^#|^$" /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[mysqld]
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
wsrep_cluster_address=gcomm://10.0.0.7,10.0.0.17,10.0.0.27,10.0.0.37
binlog_format=ROW
default_storage_engine=InnoDB
wsrep_slave_threads= 8
wsrep_log_conflicts
innodb_autoinc_lock_mode=2
wsrep_node_address=10.0.0.37
wsrep_cluster_name=pxc-cluster
wsrep_node_name=pxc-cluster-node-4
pxc_strict_mode=ENFORCING
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth="sstuser:s3cretPass"
[root@pxc4 ~]#systemctl start mysql
[root@pxc4 ~]#mysql -uroot -pmagedu
Server version: 5.7.27-30-57-log Percona XtraDB Cluster (GPL), Release rel30,
Revision
mysql> SHOW STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 4 |
+--------------------+-------+
1 row in set (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb1 |
| testdb2 |
| testdb3 |
+--------------------+
8 rows in set (0.00 sec)
#将其它节点的配置文件加以修改
[root@pxc1 ~]#vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
wsrep_cluster_address=gcomm://10.0.0.7,10.0.0.17,10.0.0.27,10.0.0.37
[root@pxc2 ~]#vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[root@pxc3 ~]#vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
#在任意节点停止服务
[root@pxc4 ~]#systemctl stop mysql
#在其它任意节点查看wsrep_cluster_size变量少了一个节点
[root@pxc1 ~]#mysql -uroot -pmagedu
Server version: 5.7.27-30-57-log Percona XtraDB Cluster (GPL), Release rel30,
Revision
mysql> SHOW STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 3 |
+--------------------+-------+
1 row in set (0.01 sec)
mysql> create database testdb4;
#在其它任意节点可看到数据已同步
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb1 |
| testdb2 |
| testdb3 |
| testdb4 |
+--------------------+
10 rows in set (0.00 sec)
#恢复服务,数据同步
[root@pxc4 ~]#systemctl start mysql
[root@pxc4 ~]#mysql -uroot -pmagedu
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb1 |
| testdb2 |
| testdb3 |
| testdb4 |
+--------------------+
10 rows in set (0.00 sec)
mysql> SHOW STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 4 |
+--------------------+-------+
1 row in set (0.01 sec)
#在三个节点上都实现
[root@centos8 ~]#dnf install mariadb-server-galera -y
[root@centos8 ~]#vim /etc/my.cnf.d/galera.cnf
#wsrep_cluster_address="dummy://"
wsrep_cluster_address="gcomm://10.0.0.8,10.0.0.18,10.0.0.28"
#启动第一节点
[root@centos8 ~]#galera_new_cluster
#再启动其它节点
[root@centos8 ~]#systemctl start mariadb
[root@centos8 ~]#ss -ntul
Netid State Recv-Q Send-Q
Local Address:Port Peer Address:Port
tcp LISTEN 0 128
0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 128
0.0.0.0:4567 0.0.0.0:*
tcp LISTEN 0 80
0.0.0.0:3306 0.0.0.0:*
tcp LISTEN 0 128
[::]:22 [::]:*
[root@centos8 ~]#mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 11
Server version: 10.3.11-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
MariaDB [(none)]> show status like "wsrep_ready";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wsrep_ready | ON |
+---------------+-------+
1 row in set (0.001 sec)
MariaDB [(none)]> SHOW STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 3 |
+--------------------+-------+
1 row in set (0.001 sec)
MariaDB [(none)]> SHOW VARIABLES LIKE 'wsrep_%'\G
MariaDB [(none)]> SHOW STATUS LIKE 'wsrep_%';
#参考仓库:https://mirrors.tuna.tsinghua.edu.cn/mariadb/mariadb-5.5.X/yum/centos7-
amd64/
yum install MariaDB-Galera-server
vim /etc/my.cnf.d/server.cnf
[galera]
wsrep_provider = /usr/lib64/galera/libgalera_smm.so
wsrep_cluster_address="gcomm://192.168.100.7,192.168.100.17,192.168.100.27"
binlog_format=row
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0
#下面配置可选项
wsrep_cluster_name = 'mycluster' 默认my_wsrep_cluster
wsrep_node_name = 'node1'
wsrep_node_address = '192.168.100.7’
#首次启动时,需要初始化集群,在其中一个节点上执行命令
/etc/init.d/mysql start --wsrep-new-cluster
#而后正常启动其它节点
service mysql start
#查看集群中相关系统变量和状态变量
SHOW VARIABLES LIKE 'wsrep_%';
SHOW STATUS LIKE 'wsrep_%';
SHOW STATUS LIKE 'wsrep_cluster_size';
高度兼容 MySQL 大多数情况下,无需修改代码即可从 MySQL 轻松迁移至 TiDB,分库分表后的MySQL 集群亦可通过 TiDB 工具进行实时迁移
水平弹性扩展 通过简单地增加新节点即可实现 TiDB 的水平扩展,按需扩展吞吐或存储,轻松应对高并发、海量数据场景。
分布式事务 TiDB 100% 支持标准的 ACID 事务
真正金融级高可用 相比于传统主从 (M-S) 复制方案,基于 Raft 的多数派选举协议可以提供金融级的 100% 数据强一致性保证,且在不丢失大多数副本的前提下,可以实现故障的自动恢复 (autofailover),无需人工介入。
一站式 HTAP 解决方案 TiDB 作为典型的 OLTP 行存数据库,同时兼具强大的 OLAP 性能,配合TiSpark,可提供一站式 HTAP解决方案,一份存储同时处理OLTP & OLAP(OLAP、OLTP的介绍和比较 )无需传统繁琐的 ETL 过程。
云原生 SQL 数据库 TiDB 是为云而设计的数据库,同 Kubernetes (十分钟带你理解Kubernetes核心概念 )深度耦合,支持公有云、私有云和混合云,使部署、配置和维护变得十分简单。 TiDB 的设计目标是 100% 的 OLTP 场景和 80% 的 OLAP 场景,更复杂的 OLAP 分析可以通过 TiSpark 项目来完成。 TiDB 对业务没有任何侵入性,能优雅的替换传统的数据库中间件、数据库分库分表等 Sharding方案。同时它也让开发运维人员不用关注数据库 Scale 的细节问题,专注于业务开发,极大的提升研发的生产力
TiDB Server 负责接收SQL请求,处理SQL相关的逻辑,并通过PD找到存储计算所需数据的TiKV地址,与TiKV交互获取数据,最终返回结果。TiDB Server 是无状态的,其本身并不存储数据,只负责计算,可以无限水平扩展,可以通过负载均衡组件(LVS、HAProxy或F5)对外提供统一的接入地址。
Placement Driver(简称PD)是整个集群的管理模块,其主要工作有三个:一是存储集群的元信息(某个Key存储在那个TiKV节点);二是对TiKV集群进行调度和负载均衡(如数据的迁移、Raft groupleader的迁移等);三是分配全局唯一且递增的事务ID
PD 是一个集群,需要部署奇数个节点,一般线上推荐至少部署3个节点。PD在选举的过程中无法对外提供服务,这个时间大约是3秒
TiKV Server 负责存储数据,从外部看TiKV是一个分布式的提供事务的Key-Value存储引擎。存储数据的基本单位是Region,每个Region负责存储一个Key Range(从StartKey到EndKey的左闭右开区间)的数据,每个TiKV节点会负责多个Region。TiKV使用Raft协议做复制,保持数据的一致性和容灾。副本以Region为单位进行管理,不同节点上的多个Region构成一个Raft Group,互为副本。数据在多个TiKV之间的负载均衡由PD调度,这里也就是以Region为单位进行调度
Mysqlslap:来自于mariadb包,测试的过程默认生成一个mysqlslap的schema,生成测试表t1,查询和插入测试数据,mysqlslap库自动生成,如果已经存在则先删除。用–only-print来打印实际的测试过程,整个测试完成后不会在数据库中留下痕迹
mysqlslap [options]
--auto-generate-sql, -a #自动生成测试表和数据,表示用mysqlslap工具自己生成的SQL脚本来测试并发压力
--auto-generate-sql-load-type=type #测试语句的类型。代表要测试的环境是读操作还是写操作还是两者混合的。取值包括:read,key,write,update和mixed(默认)
--auto-generate-sql-add-auto-increment #代表对生成的表自动添加auto_increment列,从5.1.18版本开始支持
--number-char-cols=N, -x N #自动生成的测试表中包含多少个字符类型的列,默认1
--number-int-cols=N, -y N #自动生成的测试表中包含多少个数字类型的列,默认1
--number-of-queries=N #总的测试查询次数(并发客户数×每客户查询次数)
--query=name,-q #使用自定义脚本执行测试,例如可以调用自定义的存储过程或者sql语句来执行测试
--create-schema #代表自定义的测试库名称,测试的schema
--commint=N #多少条DML后提交一次
--compress, -C #如服务器和客户端都支持压缩,则压缩信息
--concurrency=N, -c N #表示并发量,即模拟多少个客户端同时执行select。可指定多个值,以逗号或者--delimiter参数指定值做为分隔符,如:--concurrency=100,200,500
--engine=engine_name, -e engine_name #代表要测试的引擎,可以有多个,用分隔符隔开。例如:--engines=myisam,innodb
--iterations=N, -i N #测试执行的迭代次数,代表要在不同并发环境下,各自运行测试多少次
--only-print #只打印测试语句而不实际执行。
--detach=N #执行N条语句后断开重连
--debug-info, -T #打印内存和CPU的相关信息
#单线程测试
mysqlslap -a -uroot -pmagedu
#多线程测试。使用--concurrency来模拟并发连接
mysqlslap -a -c 100 -uroot -pmagedu
#迭代测试。用于需要多次执行测试得到平均值
mysqlslap -a -i 10 -uroot -pmagedu
mysqlslap ---auto-generate-sql-add-autoincrement -a
mysqlslap -a --auto-generate-sql-load-type=read
mysqlslap -a --auto-generate-secondary-indexes=3
mysqlslap -a --auto-generate-sql-write-number=1000
mysqlslap --create-schema world -q "select count(*) from City”
mysqlslap -a -e innodb -uroot -pmagedu
mysqlslap -a --number-of-queries=10 -uroot -pmagedu
#测试同时不同的存储引擎的性能进行对比
mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --iterations=5 --
engine=myisam,innodb --debug-info -uroot -pmagedu
#执行一次测试,分别50和100个并发,执行1000次总查询
mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --debug-info -uroot -pmagedu
#50和100个并发分别得到一次测试结果(Benchmark),并发数越多,执行完所有查询的时间越长。为了准确起见,可以多迭代测试几次
mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --iterations=5 --debug-info -uroot -pmagedu
#打开独立表空间
innodb_file_per_table = 1
#MySQL 服务所允许的同时会话数的上限,经常出现Too Many Connections的错误提示,则需要增大此值max_connections = 8000
#所有线程所打开表的数量
open_files_limit = 10240
#back_log 是操作系统在监听队列中所能保持的连接数
back_log = 300
#每个客户端连接最大的错误允许数量,当超过该次数,MYSQL服务器将禁止此主机的连接请求,直到MYSQL服务器重启或通过flush hosts命令清空此主机的相关信息
max_connect_errors = 1000
#每个连接传输数据大小.最大1G,须是1024的倍数,一般设为最大的BLOB的值
max_allowed_packet = 32M
#指定一个请求的最大连接时间
wait_timeout = 10
# 排序缓冲被用来处理类似ORDER BY以及GROUP BY队列所引起的排序
sort_buffer_size = 16M
#不带索引的全表扫描.使用的buffer的最小值
join_buffer_size = 16M
#查询缓冲大小
query_cache_size = 128M
#指定单个查询能够使用的缓冲区大小,缺省为1M
query_cache_limit = 4M
# 设定默认的事务隔离级别
transaction_isolation = REPEATABLE-READ
# 线程使用的堆大小. 此值限制内存中能处理的存储过程的递归深度和SQL语句复杂性,此容量的内存在每次连接时被预留.
thread_stack = 512K
# 二进制日志功能
log-bin
#二进制日志格式
binlog_format=row
#InnoDB使用一个缓冲池来保存索引和原始数据, 可设置这个变量到物理内存大小的80%
innodb_buffer_pool_size = 24G
#用来同步IO操作的IO线程的数量
innodb_file_io_threads = 4
#在InnoDb核心内的允许线程数量,建议的设置是CPU数量加上磁盘数量的两倍
innodb_thread_concurrency = 16
# 用来缓冲日志数据的缓冲区的大小
innodb_log_buffer_size = 16M
#在日志组中每个日志文件的大小
innodb_log_file_size = 512M
# 在日志组中的文件总数
innodb_log_files_in_group = 3
# SQL语句在被回滚前,InnoDB事务等待InnoDB行锁的时间
innodb_lock_wait_timeout = 120
#慢查询时长
long_query_time = 2
#将没有使用索引的查询也记录下来
log-queries-not-using-indexes
阿里巴巴Java开发手册
58到家数据库30条军规解读
http://zhuanlan.51cto.com/art/201702/531364.htm
业务名称:xxx
线上环境:xxx.db
开发环境:xxx.rdb
测试环境:xxx.tdb
从库在名称后加-s标识,备库在名称后加-ss标识
线上从库:xxx-s.db
线上备库:xxx-sss.db
认)
–auto-generate-sql-add-auto-increment #代表对生成的表自动添加auto_increment列,从5.1.18版本开始支持
–number-char-cols=N, -x N #自动生成的测试表中包含多少个字符类型的列,默认1
–number-int-cols=N, -y N #自动生成的测试表中包含多少个数字类型的列,默认1
–number-of-queries=N #总的测试查询次数(并发客户数×每客户查询次数)
–query=name,-q #使用自定义脚本执行测试,例如可以调用自定义的存储过程或者sql语句来执行测试
–create-schema #代表自定义的测试库名称,测试的schema
–commint=N #多少条DML后提交一次
–compress, -C #如服务器和客户端都支持压缩,则压缩信息
–concurrency=N, -c N #表示并发量,即模拟多少个客户端同时执行select。可指定多个值,以逗号或者–delimiter参数指定值做为分隔符,如:–concurrency=100,200,500
–engine=engine_name, -e engine_name #代表要测试的引擎,可以有多个,用分隔符隔开。例如:–engines=myisam,innodb
–iterations=N, -i N #测试执行的迭代次数,代表要在不同并发环境下,各自运行测试多少次
–only-print #只打印测试语句而不实际执行。
–detach=N #执行N条语句后断开重连
–debug-info, -T #打印内存和CPU的相关信息
##### mysqlslap示例
```bash
#单线程测试
mysqlslap -a -uroot -pmagedu
#多线程测试。使用--concurrency来模拟并发连接
mysqlslap -a -c 100 -uroot -pmagedu
#迭代测试。用于需要多次执行测试得到平均值
mysqlslap -a -i 10 -uroot -pmagedu
mysqlslap ---auto-generate-sql-add-autoincrement -a
mysqlslap -a --auto-generate-sql-load-type=read
mysqlslap -a --auto-generate-secondary-indexes=3
mysqlslap -a --auto-generate-sql-write-number=1000
mysqlslap --create-schema world -q "select count(*) from City”
mysqlslap -a -e innodb -uroot -pmagedu
mysqlslap -a --number-of-queries=10 -uroot -pmagedu
#测试同时不同的存储引擎的性能进行对比
mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --iterations=5 --
engine=myisam,innodb --debug-info -uroot -pmagedu
#执行一次测试,分别50和100个并发,执行1000次总查询
mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --debug-info -uroot -pmagedu
#50和100个并发分别得到一次测试结果(Benchmark),并发数越多,执行完所有查询的时间越长。为了准确起见,可以多迭代测试几次
mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --iterations=5 --debug-info -uroot -pmagedu
#打开独立表空间
innodb_file_per_table = 1
#MySQL 服务所允许的同时会话数的上限,经常出现Too Many Connections的错误提示,则需要增大此值max_connections = 8000
#所有线程所打开表的数量
open_files_limit = 10240
#back_log 是操作系统在监听队列中所能保持的连接数
back_log = 300
#每个客户端连接最大的错误允许数量,当超过该次数,MYSQL服务器将禁止此主机的连接请求,直到MYSQL服务器重启或通过flush hosts命令清空此主机的相关信息
max_connect_errors = 1000
#每个连接传输数据大小.最大1G,须是1024的倍数,一般设为最大的BLOB的值
max_allowed_packet = 32M
#指定一个请求的最大连接时间
wait_timeout = 10
# 排序缓冲被用来处理类似ORDER BY以及GROUP BY队列所引起的排序
sort_buffer_size = 16M
#不带索引的全表扫描.使用的buffer的最小值
join_buffer_size = 16M
#查询缓冲大小
query_cache_size = 128M
#指定单个查询能够使用的缓冲区大小,缺省为1M
query_cache_limit = 4M
# 设定默认的事务隔离级别
transaction_isolation = REPEATABLE-READ
# 线程使用的堆大小. 此值限制内存中能处理的存储过程的递归深度和SQL语句复杂性,此容量的内存在每次连接时被预留.
thread_stack = 512K
# 二进制日志功能
log-bin
#二进制日志格式
binlog_format=row
#InnoDB使用一个缓冲池来保存索引和原始数据, 可设置这个变量到物理内存大小的80%
innodb_buffer_pool_size = 24G
#用来同步IO操作的IO线程的数量
innodb_file_io_threads = 4
#在InnoDb核心内的允许线程数量,建议的设置是CPU数量加上磁盘数量的两倍
innodb_thread_concurrency = 16
# 用来缓冲日志数据的缓冲区的大小
innodb_log_buffer_size = 16M
#在日志组中每个日志文件的大小
innodb_log_file_size = 512M
# 在日志组中的文件总数
innodb_log_files_in_group = 3
# SQL语句在被回滚前,InnoDB事务等待InnoDB行锁的时间
innodb_lock_wait_timeout = 120
#慢查询时长
long_query_time = 2
#将没有使用索引的查询也记录下来
log-queries-not-using-indexes
阿里巴巴Java开发手册
58到家数据库30条军规解读
http://zhuanlan.51cto.com/art/201702/531364.htm
业务名称:xxx
线上环境:xxx.db
开发环境:xxx.rdb
测试环境:xxx.tdb
从库在名称后加-s标识,备库在名称后加-ss标识
线上从库:xxx-s.db
线上备库:xxx-sss.db