DBA笔记-第六部分(索引)

创建索引

show create table a;
+-------+-------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                      |
+-------+-------------------------------------------------------------------------------------------------------------------+
| a     | CREATE TABLE `a` (
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-------+-------------------------------------------------------------------------------------------------------------------+

首先我有一个表a 里面有两个列 a和b ,要对a列创建一个普通索引,对b列创建唯一(不能重复)索引  (key和index一样)

alter table a add index idx_a(a);

alter table a add unique index idx_b(b);

show create table a;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                       |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| a     | CREATE TABLE `a` (
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  UNIQUE KEY `idx_b` (`b`),
  KEY `idx_a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+

 那么对于修改表时会不会阻塞,也就是哪些操作能执行,哪些不能执行呢?

首先msyql5.6以后会把修改索引记录到内存Redo日志中,这个日志大小是可以查看修改的,修改较大的表时如果这个日志大小不够,那么online的DDL操作会报错或失败。修改表之前建议调大这个全局变量,配置高的可以设置为1G ,但是在线上我们一般不使用alter table操作,因为主从会有延时(下面讲解)。

set global innodb_online_alter_log_max_size=512*1024*1024;

show variables like 'innodb%max%';
+----------------------------------+------------+
| Variable_name                    | Value      |
+----------------------------------+------------+
| innodb_adaptive_max_sleep_delay  | 150000     |
| innodb_change_buffer_max_size    | 25         |
| innodb_compression_pad_pct_max   | 50         |
| innodb_file_format_max           | Barracuda  |
| innodb_ft_max_token_size         | 84         |
| innodb_io_capacity_max           | 2000       |
| innodb_max_dirty_pages_pct       | 75.000000  |
| innodb_max_dirty_pages_pct_lwm   | 0.000000   |
| innodb_max_purge_lag             | 0          |
| innodb_max_purge_lag_delay       | 0          |
| innodb_max_undo_log_size         | 1073741824 |
| innodb_online_alter_log_max_size | 134217728  |-- 就是这条,大小为128m,128*1024*1024
+----------------------------------+------------+

删除索引

删除索引idx_b,注意这些都是对表的修改,不要写成drop table  a index .......

alter table a drop index idx_b;

show create table a;
+-------+----------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                           |
+-------+----------------------------------------------------------------------------------------------------------------------------------------+
| a     | CREATE TABLE `a` (
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  KEY `idx_a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------+

主从复制

 举个最简单的例子:

主服务器 (Master)
+----------------+
|    数据库      |
|                |
|  二进制日志    |
|                |
+----------------+
         |
         | 复制数据(Binary Log)
         |
从服务器 (Slave)
+----------------+
|    数据库      |
|                |
|  中继日志      |
|                |
+----------------+

为什么尽量不使用alter table

如果使用alter table 会导致出现五分钟时间差。mysql是逻辑备份,oracle是物理备份

1. 锁定问题
表锁定:

在执行 ALTER TABLE 时,MySQL 需要对整个表进行锁定。这个锁定可能会导致其他数据库操作(如查询和写入)被阻塞,影响系统的并发性能。对于高负载系统或业务高峰期,这种锁定会导致显著的性能下降。
行级锁定:

虽然某些操作可能只需要行级锁定,但仍然可能会对性能产生影响,特别是当操作需要对大量数据进行修改时。


2. 操作时间
长时间运行:

一些 ALTER TABLE 操作可能需要很长时间才能完成,特别是当表很大或者操作非常复杂时。在此期间,表可能会被锁定,导致应用程序无法访问数据。
影响性能:

即使操作可以在后台完成,数据库在执行这些操作时通常会消耗大量的I/O和CPU资源,可能会影响到其他数据库操作的性能。


3. 在线操作的复杂性
在线模式的限制:

虽然 MySQL 在 5.6 及更高版本中引入了“在线”模式的 ALTER TABLE(即 ALGORITHM=INPLACE),但并不是所有的 ALTER TABLE 操作都可以完全无锁地进行。某些操作仍然可能需要锁定表,或者在某些情况下无法以完全在线的方式进行。
版本和存储引擎:

不同的 MySQL 版本和存储引擎对 ALTER TABLE 支持的在线操作的能力不同。例如,InnoDB 存储引擎在较新的版本中对在线 DDL 操作支持较好,但在旧版本中可能存在限制。


4. 回滚和恢复
数据恢复:

如果 ALTER TABLE 操作失败,可能需要回滚,回滚过程可能会对数据库性能产生影响,并且可能导致数据不一致。
备份和恢复:

在执行 ALTER TABLE 之前,通常需要确保数据库有完整的备份,以防操作失败或发生其他问题时能够恢复数据。


5. 影响应用程序
应用程序停机时间:

如果操作时间较长,可能会导致应用程序在执行 ALTER TABLE 期间无法访问数据库,影响业务运营。
兼容性:

一些应用程序可能与表结构变化不兼容,特别是在执行重大变更时,例如添加或删除列,可能需要修改应用程序代码。


避免影响的方法
使用在线 DDL:

对于支持在线 DDL 的版本和存储引擎,可以使用 ALGORITHM=INPLACE 或 LOCK=NONE 来减少锁定和停机时间。
分阶段进行:

对于较大的表,可以考虑将 ALTER TABLE 操作分阶段进行,例如分批次添加索引或分段修改表结构。
非高峰时段操作:

尽量在数据库负载较低的非高峰时段进行结构修改,以减少对用户的影响。
备份和测试:

在进行生产环境的 ALTER TABLE 操作之前,确保进行充分的备份,并在测试环境中模拟操作,评估对性能的影响。

  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值