数据库部署和运维

0、概要

1、如何更新给⼀个⼤表建索引

2、如何批量删除N⾏记录, 有什么注意事项

3、如何删除表?

4MySQL如何扩容

5、如何排查因为MySQL导致CPU占⽤⾼的问题?

6MySQL数据库磁盘IO使⽤⾼,请问如何进⾏排查?

7、如何批量插⼊⼤量数据?

8、数据备份和恢复

1、如何更新给⼀个⼤表建索引

出现概率: ★★★★

这个问题考察的点: 线上⾼并发下的添加⼤表建索引

当表数据量很⼤时,建⽴索引或者修改表结构会很慢,⽽且在操作的过程中,数据库甚⾄处于死锁状态,那么有没有其他的好的办法呢?

⽅式1影⼦策略

创建⼀张与原表(tb)结构相同的新表(tb_new

在新表上创建索引

重命名原表为其他表名(tb => tbtmp),新表重为原表名tbnew => tb),此时新表(tb)承担业务

为原表(tb_tmp)新增索引

交换表,新表改回最初的名称(tb => tbnew),原表最初的名称tbtmp => tb),原表(tb)重新承担业务

把新表数据导⼊原表(即把新表承担业务期间产⽣的数据和到原表中)

# 以下sql对应上⾯六步

create table tb_new like tb;

alter table tb_new add index idx_col_name (col_name);

rename table tb to tb_tmp, tb_new to tb;

alter table tb_tmp add index idx_col_name (col_name);

rename table tb to tb_new, tb_tmp => tb;

insert into tb (col_name1, col_name2) select col_name1, col_name2 from tb_new;

在⽣产环境, 这个⽅式有⽐较严重的问题, 步骤3之后,新表改为原表名后(tb)开始承担业务,步骤3到结束之前这段时间的新产⽣的数据都是存在新表中的,但是如果有业务对⽼数据进⾏修改或删除操作,那将⽆法实现,所以步骤3到结束这段时间可能会产⽣数据(更新和删除)丢失。

⽅式2、利⽤辅助⼯具 Percona Toolkit 是⼀组⾼级的命令⾏⼯具,⽤来管理 MySQL 和系统任务,主要包括:

验证主节点和复制数据的⼀致性

有效的对记录⾏进⾏归档

找出重复的索引

总结 MySQL 服务器

从⽇志和 tcpdump 中分析查询

问题发⽣时收集重要的系统信息

在线修改表结构

⼯作原理如下:

如果存在外键,根据 alter-foreign-keys-method 参数的值,检测外键相关的表,做相应设置的处理。没有使⽤ alter-foreign-keys-method 指定特定的值,该⼯具不予执⾏

创建⼀个新的空表,其命名规则是:下划线 + 原表名 +new—-原表名_new

根据 alter 语句,更新新表的表结构;
创建触发器,⽤于记录从拷⻉数据开始之后,对源数据表继续进⾏数据修改的操作记录下来,⽤于数据拷⻉结束后,执⾏这些操作,保证数据不会丢失。如果表中已经定义了触发器这个⼯具就不能⼯作了。

拷⻉数据,从源数据表中拷⻉数据到新表中。

修改外键相关的⼦表,根据修改后的数据,修改外键关联的⼦表。

rename 源数据表为 old 表,把新表 rename 为源表名,其通过⼀个 RENAME TABLE 同时处理两个表,实现原⼦操作。(RENAME TABLE dbteamdb.user TO dbteamdb.userold, dbteamdb.usernew TO dbteamdb.user

 old 表删除、删除触发器。

⽅式3、凌晨进⾏维护, 添加索引, ⼀部分公司也是这么做的, 但是不够灵活,遇到⼀些紧急情况还是⽅式2更好些。

2 如何批量删除N⾏记录, 有什么注意事项

出现概率: ★★★★

因为批量删除⼤表⼤量数据时, 数据会锁表, 在业务⾼峰时会导致 数据库CPU暴涨, 降低服务器性能, 可能会造成数据库雪崩现象。

这个也是每个线上开发⼈员可能遇到的业务场景。

⽅式1、删除⼤表的多⾏数据时,会超出innod block table size的限制,最⼩化的减少锁表的时间的⽅案是:

选择不需要删除的数据,并把它们存在⼀张相同结构的空表⾥

重命名原始表,并给新表命名为原始表的原始表名

删掉原始表

这个会有⼀个问题, 正式环境删除间隙的数据同步问题。

⽅式2、将批量删除任务拆减成 N个⼩删除任务, ⽐如只删1w条后, 将删除任务压⼊到异步队列等待执⾏.

⽅式3、删除表上的索引, 在删除数据, 可以提⾼效率, 但是不太适合线上环境.

3、如何删除表

出现概率: ★★★★

这个是如何批量删除N⾏记录的延伸问题.

如果我们清空表数据,建议直接使⽤truncate,效率上truncate远⾼于delete,在另⼀篇⽂章讲mysql的,可以得知,我们truncate不⾛事务,不会锁表,也不会产⽣⼤量⽇志写⼊⽇志⽂件,我们访问log执⾏⽇志可以发现每次delete都有记录。truncate table tablename 会⽴刻释放盘空间,并重autoincrement的值,delete 删除不释放磁盘空间,insert会覆盖之前的数据上,因为我们创建表的时候有⼀个创建版本号。

4MySQL如何扩容

出现概率: ★★★

⽬前可⽤⽅案

1)MySQL的复制:
⼀个Master数据库,多个Salve,然后利⽤MySQL的异步复制能⼒实现读写分离,这个⽅案⽬前应⽤⽐较⼴泛,这种技术对于以读为主的应⽤很有效。 数据切分(MySQLSharding策略):
垂直切分:⼀种是按照不同的表(或者Schema)来切分到不同的数据库(主机)之上,这种切可以称之为数据的垂直(纵向)切分;垂直切分的思路就是分析表 间的聚合关系,把关系紧密的表放在⼀起。

⽔平切分:另外⼀种则是根据表中的数据的逻辑关系,将同⼀个表中的数据按照某种条件拆分到多台数据库(主机)上⾯,这种切分称之为数据的⽔平(横向)切分。

2)、通过集群扩展:MySQL Cluster(NDB Cluster)

类似于MongoDB的动态扩容策略。

MySQL Cluster是⼀套具备可扩展能⼒、实时、内存内且符合ACID要求的事务型数据库,其将99.999%⾼可⽤性与低廉的开源总体拥有成本相结合。在设计思路⽅⾯,MySQL Cluster采⽤⼀套分布式多主架构并借此彻底消灭了单点故障问题。MySQL Cluster能够横向扩展⾄商⽤硬件之上,能够通过⾃动分区以承载读取与写⼊敏感型⼯作负载,并可通过SQLNoSQL接⼝实现访问。

采⽤NDB存储引擎,有数据节点,SQL节点,和管理节点(1个,配置要求低)

3)、分库分表分区

5、如何排查因为MySQL导致CPU占⽤⾼的问题?

出现概率: ★★★
在问题出现之前, 我们需要做的是加强监控, ⽐如当CPU暴涨到85%时就进⾏报警, 这样当有问题时, 开发⼈员和运维⼈员可以第⼀时间收到报警, 并处理, ⽽不是让⽤户报出来: 你家APP是不是⼜崩了, 卡死了。

我们平时遇到⼤部分MySQL导致CPU占⽤⾼的情况是因为慢查询实例出现CPU飙升。这种情况表现是QPS(每秒执⾏的查询次数)不⾼;查询执⾏效率低、执⾏时需要扫描⼤量表中数据。此时可能是由于存在慢查询导致,查询执⾏效率低,为了获取预期的结果就需要访问⼤量的数据,导致平均逻辑IO增⾼,此时就会是CPU利⽤率过⾼。

此时需要DBA,定位效率低的查询、优化查询的执⾏效率、降低查询执⾏的成本。

具体定位的过程可以参考:

1)、通过在控制台下载慢查询⽇志,定位效率低的SQL并进⾏优化
2)、也可以通过  show processlist ;   show full processlist ; 命令查看当前执⾏的查询,反复执⾏,找到慢查询的process ID ,运⾏kill 慢查询的id 命名杀掉慢查询进程。

同时MySQL处在⾼负载环境下,磁盘IO读写过多,也会占⽤很多资源,必然会使CPU占⽤过⾼。CPU过⾼,可以从下⾯⼏个⽅向进⾏排查问题和优化:1)、打开慢查询⽇志,查询是否是某个SQL语句占⽤过多资源,如果是的话,可以对SQL语句进⾏优化,⽐如优化 insert 语句、优化 group by 语句、优化 order by 句、优化 join 语句等等;

2)、考虑索引问题;

3)、定期分析表,使 optimize table 

4)、优化数据库对象;

5)、考虑是否是锁问题;
6)、调整⼀些MySQL Server参数,⽐如keybuffersizetablecacheinnodbbufferpoolsizeinnodblogfile_size等等;7)、如果数据量过⼤,可以考虑使⽤MySQL集群或者搭建⾼可⽤环境。

8)、考虑磁盘是否满了

6MySQL数据库磁盘IO使⽤⾼,请问如何进⾏排查?

出现概率: ★★★

我们以mysql5.7版本为例,结合 performance_schema 来查看MySQL数据库的各种指标。IO的话,可以查看这张表:

performance_schema.file_instances :列出了⽂件I O操作及其相关⽂件的⼯具实例

⼀般遇到问题时的排查思路:

1、慢SQL排除

2、硬件问题-RAID降级,磁盘故障等排除

3innodbloginnodbbufferpoolwait相关配置

4IO相关参数配置

innodb_flush_method = O_DIRECT

innodb_file_per_table = 1

innodb_doublewrite = 1

delay_key_write

innodb_read_io_threads

innodb_read_io_threads

innodb_io_capacity

innodb_flush_neighbors

sync_binlog

其中可以主要关注:sync_binlog, binlog刷新的参数,默认是1

mysql> show variables like '%sync_bin%';

+--------------+-------+

| Variable_name | Value |

+---------------+-------+

| sync_binlog   | 1   |

+---------------+-------+

1 row in set (0.00 sec)

syncbinlog1, 表示每次务提交MySQL将进⾏⼀fsync之类的同步指令来binlogcache中的数据强制写⼊磁盘,频繁的写盘导致磁盘IO居⾼不下,将sync_binlog调整为500

⼤家都知道,影响数据库最⼤的性能问题就是磁盘IO,为了提升数据库的IOPS,可以使⽤SSD或者PCIE-SSD⾼速磁盘。内存⽅⾯也很重要,内存可以缓存热点数据和存储引擎⽂件,避免产⽣过多的物理IO,可以增加物理内存来提⾼数据库的并发和读写性能。

最后也建议:最好部署相关的监控平台或者对⽐历史性能记录,结合业务以及负载来分析。

7、如何批量插⼊⼤量数据?

出现概率: ★★★

1)、⾃⼰也循环⼀条⼀条插⼊, 缺点时因为频繁建⽴连接, ⽐较耗时

2)、减少连接资源,拼接⼀条sql,这样写⼀次正常插⼊⼀万条基本问题不⼤,除⾮数据很⻓,应付普通的批量插⼊够⽤了,⽐如:批量⽣成卡号,批量⽣成随机码等等。

3)、使⽤存储过程

delimiter $$$

create procedure zqtest()

begin

declare i int default 0;

set i=0;

start transaction;

while i<80000 do

 //your insert sql

set i=i+1;

end while;

commit;

end

$$$

delimiter;

call zqtest();

4)、使⽤MYSQL LOCAL_INFILE

LOAD DATA LOCAL INFILE 'F:\\milo.csv' INTO TABLE test

FIELDS TERMINATED BY ','

ENCLOSED BY '"'

LINES TERMINATED BY '\r\n'

IGNORE 1 LINES

(id, name)

时间对⽐:

经过测试插⼊1w条数据时候与拼装批量插⼊语句时间差别不⼤,当插⼊数量达到10w出现了明显的时间差:

拼装批量插⼊语句花费时间:6.83s

LOAD DATA LOCAL INFILE实现⼤批量插⼊花费时间:1.23s

当表格的字段更多数据量更⼤出现的时间差就越⼤。

总结:当需要进⾏⼤批量数据插⼊的时候,可以优先考虑LOAD DATA LOCAL INFILE实现⽅式。

8、数据备份和恢复

出现概率: ★★★★

Mysql 提供了 mysqldumpibbackupreplication ⼯具来备份, 关于备份需要了解的⼏个概念:

1)、数据备份按备份类型:

热备:在数据库运⾏过程中直接备份, 读写操作均可执⾏

冷备:在数据库停⽌的情况下备份,读写操作均不可进⾏,⼀般直接复制相关的物理⽂件即可
温备:在数据库运⾏过程中备份, 读操作可执⾏;但写操作不可执⾏,但对数据库操作有影响,如加个全局读锁以保证备份数据⼀致性

关于热备原理:

双机热备就是使⽤MySQL提供的⼀种主从备份机制实现。所谓双机热备其实是⼀个复制的过程,复制过程中⼀个服务器充当主服务器,⼀个或多个服务器充当从服务。这个复制的过程实质上是从服务器复制主服务器上MySQL的⼆进制⽇志(bin-log),并在从服务器上还原主服务器上的sql语句操作,这样只要两个数据库的初态是⼀样的,就能⼀直同步。

双机热备的实现需要MySQL的版本⾼于3.2.。另外由于这种备份是基于MySQL⼆进制⽇志实现,所以主从服务器上的MySQL版本最好能够⼀样,⾄少从服务器的MySQL版本不可以低于主服务器的数据库版本。因为MySQL不同的版本之间⼆进制⽇志可能不⼀样。

当然这种复制和重复都是MySQL⾃动实现的,我们只需要配置即可。

上图中有两个服务器, 演示了从⼀个主服务器(master 把数据同步到从服务器(slave)的过程。

这是⼀个主-从复制的例⼦。 -主互相复制只是把上⾯的例⼦反过来再做⼀遍。

2)、按备份内容:

⽇志备份:主要备份 bin-log ⽇志,然后 replay 来完成 point-in-time

完全备份:对数据库⼀个完整的备份
增量备份:在上次完全备份的基础上对更改部分进⾏备份(MySQL 没真正的增量备份,⼀般通过 bin-log 完成,要借助第三⽅⼯具才能实现)3)、按备份⽂件:

逻辑⽂件:指备份出的⽂件可读,⼀般指 SQL 语句(适⽤库升级,迁移,但恢复时间较⻓需要执⾏ SQL 语句)

物理⽂件:指复制数据库的物理⽂件

其中 mysqldump 是属于逻辑备份,也是最常⻅的备份⼯具了,缺点在于备份和恢复速度不是特别快

4)、最后关于备份数据, 别忘了我们也要备份 binlog
如果有 DBA 告诉你,这个数据库能够恢复到两个个⽉内任何状态,这说明了,这个数据库的 binlog ⽇志⾄少保留了两个⽉。备份 binlog 的好处: 可以实现基于任意时间点的恢复

可以⽤于误操作数据闪回

可以⽤于审计

5)、关于备份恢复
a)、对于使⽤mysqldump进⾏逻辑备份的⽂件,  mysql -u root -p [dbname] < backup.sql  进⾏恢复即可
b)xtrabackup 备份全量恢复
Percona-xtrabackup Percona公司开发的⼀个⽤于MySQL数据库物理热备的备份⼯具,⽀持MySQLPercona serverMariaDB,开源免费,是⽬前较为受欢迎的主流备份⼯具。xtrabackup只能备份innoDBxtraDB两种数据引擎的表,⽽不能备份MyISAM数据表。

MySQL冷备、mysqldumpMySQL热拷⻉都⽆法实现对数据库进⾏增量备份。在实际⽣产环境中增量备份是⾮常实⽤的,如果数据⼤于50G100G,存储空间⾜够的情况下,可以每天进⾏完整备份,如果每天产⽣的数据量较⼤,需要定制数据备份策略。例如每周实⽤完整备份,周⼀到周六实⽤增量备份。⽽Percona-Xtrabackup就是为了实现增量备份⽽出现的⼀款主流备份⼯具,

xtrabackup包含两个主要的⼯具,即xtrabackupinnobackupex,⼆者区别如下:

1xtrabackup只能备份innodbxtradb两种引擎的表,⽽不能备份myisam引擎的表;
2innobackupex是⼀个封装了xtrabackupPerl脚本,⽀持同时备份innodbmyisam,但在对myisam备份时需要加⼀个全局的读锁。还有就是myisam不⽀持增量备份

Xtrabackup备份原理

Xtrabackup备份流程图(xtrabackup备份过程中,先备份innodb表,再备份⾮innodb表):

恢复过程如下:

#步骤⼀:解压(如果没有压缩可以忽略这⼀步)

innobackupex--decompress<备份⽂件所在⽬录>

#步骤⼆:应⽤⽇志

innobackupex--apply-log<备份⽂件所在⽬录>

#步骤三:复制备份⽂件到数据⽬录

innobackupex--datadir=<MySQL数据⽬录>--copy-back<备份⽂件所在⽬录>

c)、基于时间点恢复

基于时间点的恢复依赖的是 binlog ⽇志,需要从 binlog 中找过从备份点到恢复点的所有⽇志,然后应⽤。

show variables like 'log_bin%';

+---------------------------------+-------+

| Variable_name                   | Value |

+---------------------------------+-------+

| log_bin                         | OFF   |

| log_bin_basename                |       |

| log_bin_index                   |       |

| log_bin_trust_function_creators | OFF   |

| log_bin_use_v1_row_events       | OFF   |

+---------------------------------+-------+

5 rows in set (0.06 sec)

查看log_bin 配置是否启⽤ binlogMysql 8.0 默认开启 binlog

如果log_bin 是关闭, 可以修改my.conf 打开. 这⾥不就展开讲binlog的恢复了,想深⼊了解的朋友可以⾃⼰研究⼀下。

结语: 对于⼀个在正式环境运⾏的系统来说, 数据是最重要的了, 代码我们可以通过git来管理, 数据只能靠我们⾃⼰进⾏备份、只有平时做好了操作, 才能在关键时刻恢复。 ⽐如这个经典案例, 如果平时做好了演练, 也就没有那么多事情了:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红红火火a

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值