MySQL连接:

client => api接口 => 连接池 => 验证用户 => mysql-server

MySQL架构:

MySQL缓存从8.0开始已经去掉了,可以选用第三方redis作为缓存,去掉的原因是:自带的缓存服务变得可有可无了,甚至有时拖累MySQL本身。

一、总结mysql常见的存储引擎以及特点:

mysql常见的存储引擎有两种,(1):MyISAM存储引擎,(2):InnoDB存储引擎,5.5版本之后默认存储引擎是InnoDB。

官方文档:https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/storage-engines.html

以下为个别的对比:

MyISAM存储引擎 InnoDB存储引擎
不支持事务 支持事务
表级锁定 行锁定
读写相互阻塞 读写阻塞与事务隔离级别相关
只缓存索引 可缓存索引和数据
不支持外键约束 支持外键约束
不支持聚集索引 支持聚集索引
读取数据较快 写入和修改较快
不支持MVCC(根据时间不同产生的多版本并发控制机制)高并发 支持MVCC(根据时间不同产生的多版本并发控制机制)高并发
崩溃恢复性较差 崩溃恢复性更好
MySQL5.5.5前默认的数据库存储引擎 MySQL5.5.5之后默认的数据库存储引擎
适用场景:只读或者写较少,表较小或者可接受长时间表处于锁定的 使用场景:频繁的事务操作
引擎文件有三个:tb_name.frm(表格式定义)、tb_name.MYD(数据文件)、tb_name.MYI(索引文件) 引擎文件有两个:tb_name.frm(表格式定义)、tb_name.ibd(数据文件)
最高支持储存256T 最高支持储存64T

服务器选项,系统变量和状态变量参考:https://dev.mysql.com/doc/refman/8.0/en/server-option-variable-reference.html

1、服务器选项通过my.cnf配置文件设置为永久生效:

比如重置密码:skip-grant-tables

2、系统(服务器)变量通过MySQL命令行查看:SHOW VARIABLES LIKE '变量值';

比如:SHOW VARIABLES LIKE 'skip_networking';

1)变量又分为会话变量(当前窗口)和全局变量(全部窗口,而且只对修改后新创建的会话有效),只有当Dynamic=yes的才能支持动态去修改

查看全局的:SHOW GLOBAL VARIABLES;

修改全局变量:SET GLOBAL system_var_name=value;  或者 SET @@global.system_var_name=value;

查看所有的:SHOW [SESSION] VARIABLES;(包括全局和session)

修改会话变量:SET [SESSION] system_var_name=value;  或者 SET @@[SESSION.]system_var_name=value;

只读变量不能去修改;

2)修改最大连接数:

2.1)查看最大连接数:mysqladmin variables | awk '$2=="max_connections" {print $2,$3,$4}'

2.2)修改变量:SET GLOBAL max_connections=4000;

重启生效要写到配置文件中:/etc/my.cnf

[mysqld]

max_connections=4000

查看变量修改情况:SHOW GLOBAL VARIABLES LIKE 'max_connections';

注意:只有5.7之前的版本才需要修改此项:

方法一:

vim /usr/lib/systemd/system/mariadb.server[Service]
# 加下面一行
LimitNOFILE=65535

方法二:

mkdir /etc/systemd/system/mariadb.service.d
cat > /etc/systemd/system/mariadb.service.d/limits.conf <EOF
[Service]
# 加下面一行
LimitNOFILE=65535
EOF

重新加载数据库:systemctl daemon-reload && systemctl restart mariadb

2.3) innodb_page_size变量修改,不建议后期修改,要修改必须删库重启才行

3)服务器状态变量:只是用于用户查看的状态信息

MariaDB [(none)]> SHOW STATUS LIKE 'Com_select';+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select    | 0     |
+---------------+-------+
1 row in set (0.002 sec)MariaDB [(none)]> SELECT User,Host FROM mysql.user;
+------+------------+
| User | Host       |
+------+------------+
| root | 127.0.0.1  |
| root | ::1        |
| root | git-server |
| root | localhost  |
+------+------------+
4 rows in set (0.000 sec)MariaDB [(none)]> SHOW STATUS LIKE 'Com_select';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select    | 1     |
+---------------+-------+
1 row in set (0.000 sec)MariaDB [(none)]>

4)创建库和表:

MariaDB [(none)]> CREATE DATABASE IF NOT EXISTS test DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected (0.000 sec)MariaDB [(none)]> use test;
Database changed
MariaDB [test]> CREATE TABLE test (ID INT AUTO_INCREMENT PRIMARY KEY,NAME VARCHAR(3));
Query OK, 0 rows affected (0.006 sec)MariaDB [test]>

测试字段多余限制的值:会存在报错(在8.0之后的版本会出现这种问题),原因是sql_mode的变量值影响的,所以不同版本会存在变量值的问题

MariaDB [test]> INSERT test(name)VALUES('a');
Query OK, 1 row affected (0.002 sec)MariaDB [test]> SELECT * FROM test;
+----+------+
| ID | NAME |
+----+------+
|  1 | a    |
+----+------+
1 row in set (0.000 sec)MariaDB [test]> INSERT test(name)VALUES('a12345');
ERROR 1406 (22001): Data too long for column 'NAME' at row 1
MariaDB [test]> 

3、MySQL8.0变化

3.1 MySQL8.0取消查询缓存功能:自带的Query Cache存在严重的可伸缩性问题,并且很容易成为严重的瓶颈。目前大多数应用都把缓存做到了应用逻辑层中,比如:使用redis或者memcache等

查询缓存的查询逻辑是根据hash计算来完成的,查询门槛低,不需要对SQL语句做任何的解析和执行,但它有个缺点,查询的语句中会区分大小写。

3.2 查询缓存原理的执行路径

3.3 查询缓存相关的服务器变量

(1)query_cache_min_res_unit:查询缓存中内存块的最小分配单位,默认4k,较小值会减少浪费,但会导致更频繁的内存分配操作,较大值会带来会带来浪费,会导致碎片过多,内存不足等问题。

(2)query_cache_limit:单个查询结果能缓存的最大值,单位字节,默认为1M,对于查询结果过大而无法缓存的语句,建议使用SQL_NO_CSCHE 。

(3)query_cache_size:查询缓存总共可用的内存空间,单位字节,必须是1024的整数倍,最小40KB,低于此值有警报。

(4)query_eache_wlock——invalidate:如果某表被其它的会话锁定,是否仍然可以从查询缓存中返回结果,默认值为OFF,表示可以在表被其它会话锁定的场景中继续从缓存返回数据,ON则表示不允许。

(5)query_cache_type:是否开启缓存功能,取值为ON,OFF,DEMAND。

3.4 SELECT 语句的缓存控制

(1)SQL_CACHE:显示指定存储查询结果于缓存之中。

(2)SQL_NO_CACHE:禁止缓存查询结果,意思是在查询时不使用缓存作为查询结果显示出来

(3)query_cache_type:参数变量

(3.1)query_cache_type的值为OFF或者0时,查询缓存功能关闭

(3.2)query_cache_type的值为ON或者1时,查询缓存功能打开,SELECT的结果符合缓存条件即会缓存,否则不予缓存,显示指定SQL_NO_CACHE,不予缓存,此为默认值。

(3.3)query_cache_type的值为DEMAND或者2时,查询缓存功能按需进行,显示指定SQL_CACHE的SELECT语句才会缓存,其它均不予缓存。

3.5 官方文档:

(3.5.1)https://mariadb.com/kb/en/library/server-system-variables/#query_cache_type

(3.5.2)https://dev.mysql.com/doc/refman/5.7/en/query-cache-configuration.html

3.6 查询是否开启缓存功能:

MariaDB [(none)]> select @@query_cache_type;
+--------------------+
| @@query_cache_type |
+--------------------+
| OFF                |
+--------------------+
1 row in set (0.000 sec)

4、查询优化的流程方法计算

5、 命中率和内存使用的估算

5、1 查询缓存中内存块的最小分配单位query_cache_min_res_unit:

(query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache

5.2 查询缓存命中率:

Qcache_hits / (Qcache_hits + Qcache_inserts) * 100%

5.3 查询缓存内存使用率:

(Qcache_cache_size - qcache_free_memory) / Qcache_cache_size * 100%

6 INDEX索引

6.1 索引介绍

索引:是排序的快速查找的特殊数据结构,定义作为查找条件的字段上,又称为键(key),索引通过存储引擎实现。

优点:

(1)可以降低服务需要扫描的数据量,减少了IO次数

(2)可以帮助服务器避免排序和使用临时表

(3)可以帮助将随机I/O转为顺寻I/O

缺点:

(1)占用额外空间,影响插入速度

6.2 索引类型

(1)B+TREE、HASH、R TREE、FULL TEXT

(2)聚簇(集)索引、非聚簇索引:数据和索引是否存储在一起

(3)主键索引、二级(辅助)索引

(4)稠密索引、稀疏索引:是否索引了每一个数据项

(5)简单索引、组合索引

(6)左前缀索引:取前面的字符做索引

(7)覆盖索引:从索引中即可取出要查询的数据,性能高

6.3 索引结构

参考文档:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

面试题:InnoDB中一颗的B+树可以存放多少行数据?

7、索引的介绍

7.1 B+Tree索引:按顺序存储,每一个叶节点到根节点的距离是相同的;左前缀索引,适合查询范围类的数据。

可是使用B+Tree索引的查询类型:(假设前提:姓、名、年龄三个字段建立了一个符合索引)

(1)全值匹配:精确索引索引列。如:姓wang,名xiaochun,年龄30

(2)匹配最左前缀:即只使用索引的第一列。如:姓wang

(3)匹配列前缀:只匹配一列值开头部分。如:姓以w开头的记录

(4)匹配范围值:如:姓ma和姓wang之间

(5)精确匹配某一列并范围匹配另一列:如姓wang,名以x开头的记录

(6)只访问索引的查询的查询

B+Tree索引的限制

(1)如不从最左列开始,则无法使用索引,如:查找名为xiaochun,或者姓为g的结尾(在用姓为索引的前提下)

(2)不能跳过索引中的列,如:查找姓wang,年龄30的,只能使用索引第一列。

特别提示:

(1)索引列的顺序和查询语句的写法应相匹配,才能更好的利用索引。

(2)为优化性能,可能需要针对相同的列但顺序不同的索引来满足不同类型的查询需求。

7.2 空间数据索引R-Tree(Geospatial indexing)

(1)MyISAM支持地理空间索引,可使用任意维度组合查询,使用特有的函数访问,常用语做地理数据存储,使用不多。

(2)InnoDB从MySQL5.7之后开始支持

7.3 全文索引(FULLTEXT)

(1)在文中查找关键字,而不是直接比较索引中的值,类似搜索引擎。

(2)InnoDB从MySQL5.6之后开始支持

7.4 索引优化

(1)独立的使用列:尽量避免其参与运算,独立的列指索引列不能是表达式的一部分,也不能是函数的参数,在where条件中,始终将索引列单独放在比较符号的一侧,尽量不要在列上进行运算(函数操作和表达式操作)

(2)左前缀索引:构建指定索引字段的左侧的字符数,要通过索引选择性(不重复的索引值和数据表的记录总数的比值)来评估,尽量使用短索引,如果可以,应该制定一个前缀长度。

(3)多列索引:AND操作时更适合使用多列索引,而非为每一个列创建单独的索引。

(4)选择合适的索引列顺序:无排序和分组时,将选择性最高放左侧。

(5)只要列中含有NULL值,就最好不要在此列设置索引,复合索引如果有NULL值,此列在使用时也不会使用索引。

(6)对于经常在where子句使用的列,最好设置索引。

(7)对于有多个列where或者order by子句,应该建立复合索引。

(8)玉玉like语句,以%或者_,开头的不会使用索引,以%结尾的会使用索引。

(9)尽量不用使用not in和<>操作,虽然可能使用索引,但性能不高。

(10)不要使用RLIKE正则表达式,会导致索引失效。

(11)查询时,能不要*就不用*,尽量写全字段名,比如:select id,name,age from students;

(12)大部分情况连接效率远大于子查询。

(13)在有大量记录的表分页时使用limit。

(14)对于经常使用的查询,可以开启查询缓存。

(15)多使用explain和profile分析查询语句。

(16)查看慢查询日志,找出执行时间长的sql语句进行优化。

8 并发控制

8.1 锁机制

(1)读锁:共享锁,也称为S锁,只读不可写(包括当前事务),多个读互不堵塞。

(2)写锁:独占锁,排它锁,也称为X锁,写锁会堵塞其他事务(不包括当前事务)的读和写。

锁粒度:

(1)表级锁:MyISAM

(2)行级锁:InnoDB

实现:

(1)存储引擎:自行实现其锁策略和锁粒度

(2)服务器级:实现了锁,表级锁,用户可显示请求

分类:

(1)隐式锁:由存储引擎自动施加锁

(2)显示锁:用户手动请求

锁策略:在锁粒度及数据安全性寻求的平衡机制

8.2 事务

(1)事务Transactions:一组原子性的SQL语句,或一个独立工作单元

(2)事务日志:记录事务信息,实现undo,redo等故障恢复功能

事务特性

ACID特性:

(1)A:atomicity原子性:整个事务中的所有操作要么全部成功执行,要么全部失败后回滚。

(2)C:consistency一致性:数据库总是从一个一致性状态转换为另一个一致性状态。

(3)I:Isolation隔离性:一个事务所做出的操作在提交之前,是不能为其它事务所见;隔离有多种隔离级别,实现并发。

(4)D:durability持久性:一旦事务提交,其所做的修改会永久保存于数据库中。

8.3 Transaction的生命周期

8.4 事务隔离级别

MySQL支持四种隔离级别,事务隔离级别从上至下更加严格

8.5 死锁:两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态。

二、MySQL日志各类类型

1、事务日志:

1.1) 事务日志:transaction log

事务日志的写入类型为“追加”,因此其操作为“顺序IO”;通常也被称为:预写式日志(write ahead logging)

事务日志文件:ib_logfile0,ib_logfile1

事务型存储引擎自行管理和使用,建议和数据文件分开存放

(1)redo log:实现WAL(write ahead log),数据更新前先记录redo log

(2)undo log:保存与执行的操作相反的操作,用于实现rollback

1.2)InnoDB事务日志相关配置:

MariaDB [(none)]> 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     | OFF      |
| innodb_log_write_ahead_size | 8192     |
+-----------------------------+----------+
8 rows in set (0.014 sec)MariaDB [(none)]>

1.3)事务日志性能优化:

innodb_flush_log_at_trx_commit=0|1|2   # 默认为1,my.cnf

1  此为默认值,日志缓冲区将写入日志文件,并在每次事务后执行刷新到硬盘;这是完全遵守ACID特性

0  提交时没有写硬盘的操作,而是每秒执行一次将日志缓冲区的提交的事务写入刷新到硬盘中,这样可以提供更好的性能,但服务器崩溃可能丢失最后一秒的事务

2  每次提交后都会写入OS的缓冲区中,但每秒才会进行一次刷新到硬盘文件中,性能比0略差一些,但操作系统或停电可能导致最后一秒的事务丢失

1.4)高并发业务行业最佳实践,是使用第三种折衷配置(=2):

1. 配置为2和配置为0,性能差异并不大,因为将数据从Log Buffer拷贝 到OS cache,虽然跨越用户态与内核态,但毕竟只是内存的数据拷贝,速度很快。

2.  配置为2和配置为0,安全性差别巨大,操作系统崩溃的概率相比MySQL应用程序崩溃的概率,小很多,设置为2,只要操作系统不崩溃,也绝对不会丢失数据。

1.5)说明:

(1)设置为1,同时sync_binlog=1表示最高级别的容错

(2) innodb_use_global_flush_log_at_trx_commit=0时,将不能用SET语句重置此变量(MariaDB10.2.6后废弃)。

2、错误日志:error log

2.1)mysqld启动和关闭过程中的输出事件信息

2.2)mysqld运行中产生的错误信息

2.3)event scheduler运行一个event时产生的日志信息

2.4)在主从复制架构中的从服务器上启动从服务器线程时产生的信息

2.5)错误文件路径

MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'log_error';
+---------------+------------------------------+
| Variable_name | Value                        |
+---------------+------------------------------+
| log_error     | /var/log/mariadb/mariadb.log |
+---------------+------------------------------+
1 row in set (0.002 sec)MariaDB [(none)]>

2.6)记录那些警告信息至错误日志文件中

centos7  mariadb 5.5 默认为1

centos8 mariadb 10.3 默认值为2

数据值越大记录的信息越详细

log_warnings=0|1|2|3...  # my.cnf

查询当前记录日志级别

MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'log_warnings';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_warnings  | 2     |
+---------------+-------+
1 row in set (0.001 sec)MariaDB [(none)]>

3、通用日志:general log

通用日志:记录对数据库的通用操作,包括错误的SQL语句,默认时不开启的,可以在命令行中临时修改

通用日志可以保存在:file(默认值)或table(mysql.general_log表)

通用日志相关设置

general_log=ON|OFF
general_log_file=HOSTNAME.log
log_output=TABLE|FILE|NONE

4、慢查询日志:slow query log

记录执行查询时长超出指定时长的操作

4.1)慢查询相关配置变量

slow_query_log=ON|OFF  # 开启或关闭慢查询,支持全局和会话,只有全局设置才会生成慢日志文件

long_query_time=N            # 慢查询的阈值,单位秒,默认为10秒

slow_query_log_file=HOSTNAME-slow.log  # 慢查询日志文件

log_slow_filter=admin | filesort,filesort_on_disk,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk  # 查询类型且查询时长超过long_query_time,则记录日志

log_queries_not_using_indexes=ON  # 不使用索引或者全索引扫描,不论是否达到慢查询阈值的语句是否记录日志,默认OFF,即不记录

log_slow_rate_limit=1  # 多少次查询才记录,mariadb特有的

log_slow_verbosity=Query_plan,explain  # 记录内容

log_slow_queries=OFF  # 同slow_query_log,mariadb 10.0/MySQL 5.6.1  版本后已删除

4.2)慢查询分析工具:mysqldumpslow

例子:

mysqldumpslow -s c -t 10 /var/log/mariadb/slow.log

4.3)使用自带的profile分析工具

# 打开后,会显示语句的执行详细过程

MariaDB [(none)]> set profiling=ON;
Query OK, 0 rows affected (0.000 sec)

查看语句,注意结果中的query_id的值

MariaDB [test]> select sleep(1) from test;
+----------+
| sleep(1) |
+----------+
|        0 |
+----------+
1 row in set (1.005 sec)MariaDB [test]> show profiles;
+----------+------------+---------------------------+
| Query_ID | Duration   | Query                     |
+----------+------------+---------------------------+
|        1 | 0.00481164 | show databases            |
|        2 | 0.00018094 | SELECT DATABASE()         |
|        3 | 0.00022328 | show databases            |
|        4 | 0.00016414 | show tables               |
|        5 | 1.00517136 | select sleep(1) from test |
+----------+------------+---------------------------+
5 rows in set (0.000 sec)MariaDB [test]>

显示语句的详细执行步骤和时长:

MariaDB [test]> show profile for query 5;  # 上面执行耗时最大的Query_ID=5
+------------------------+----------+
| Status                 | Duration |
+------------------------+----------+
| Starting               | 0.003030 |
| Checking permissions   | 0.000012 |
| Opening tables         | 0.000016 |
| After opening tables   | 0.000004 |
| System lock            | 0.000003 |
| Table lock             | 0.000005 |
| Init                   | 0.000576 |
| Optimizing             | 0.000009 |
| Statistics             | 0.000012 |
| Preparing              | 0.000012 |
| Executing              | 0.000002 |
| Sending data           | 0.000547 |
| User sleep             | 1.000807 |
| End of update loop     | 0.000021 |
| Query end              | 0.000002 |
| Commit                 | 0.000032 |
| Closing tables         | 0.000005 |
| Unlocking tables       | 0.000002 |
| Closing tables         | 0.000009 |
| Starting cleanup       | 0.000002 |
| Freeing items          | 0.000005 |
| Updating status        | 0.000055 |
| Reset for next command | 0.000004 |
+------------------------+----------+
23 rows in set (0.003 sec)MariaDB [test]>

显示CPU的使用情况:

MariaDB [test]> show profile cpu for query 5;
+------------------------+----------+----------+------------+
| Status                 | Duration | CPU_user | CPU_system |
+------------------------+----------+----------+------------+
| Starting               | 0.003030 | 0.000365 |   0.000000 |
| Checking permissions   | 0.000012 | 0.000010 |   0.000000 |
| Opening tables         | 0.000016 | 0.000015 |   0.000000 |
| After opening tables   | 0.000004 | 0.000004 |   0.000000 |
| System lock            | 0.000003 | 0.000003 |   0.000000 |
| Table lock             | 0.000005 | 0.000005 |   0.000000 |
| Init                   | 0.000576 | 0.000131 |   0.000000 |
| Optimizing             | 0.000009 | 0.000008 |   0.000000 |
| Statistics             | 0.000012 | 0.000013 |   0.000000 |
| Preparing              | 0.000012 | 0.000011 |   0.000000 |
| Executing              | 0.000002 | 0.000002 |   0.000000 |
| Sending data           | 0.000547 | 0.000543 |   0.000000 |
| User sleep             | 1.000807 | 0.000866 |   0.000000 |
| End of update loop     | 0.000021 | 0.000019 |   0.000000 |
| Query end              | 0.000002 | 0.000002 |   0.000000 |
| Commit                 | 0.000032 | 0.000027 |   0.000000 |
| Closing tables         | 0.000005 | 0.000005 |   0.000000 |
| Unlocking tables       | 0.000002 | 0.000002 |   0.000000 |
| Closing tables         | 0.000009 | 0.000009 |   0.000000 |
| Starting cleanup       | 0.000002 | 0.000002 |   0.000000 |
| Freeing items          | 0.000005 | 0.000005 |   0.000000 |
| Updating status        | 0.000055 | 0.000055 |   0.000000 |
| Reset for next command | 0.000004 | 0.000004 |   0.000000 |
+------------------------+----------+----------+------------+
23 rows in set (0.000 sec)MariaDB [test]>

5、二进制日志:binary log

功能:通过“重放”日志文件中的事件来生成数据副本

注意:建议二进制日志和数据文件分开存放

(1)记录导致数据改变或潜在导致数据改变的SQL语句

(2)记录已提交的日志

(3)不依赖于存储引擎类型

5.1)二进制日志记录三种格式

(1)基于“语句”记录:statement,记录语句,默认模式(mariadb 10.2.3 版本以下),日志量较少

(2)基于“行”记录:row,记录数据,日志量较大,更加安全,建议使用该格式

(3)混合模式:mixed,让系统自行判断该基于哪种方式进行,默认模式(mariadb 10.2.4 版本以上)

查询配置状态:

MariaDB [test]> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | MIXED |
+---------------+-------+
1 row in set (0.007 sec)MariaDB [test]>

5.2)二进制日志文件的构成

(1)日志文件:mysql | mariadb-bin.文件名后缀,二进制格式。如:mariadb-bin.000001,maridb-bin.000002

(2)索引文件:mysql | mariadb-bin.index,文本格式

5.3)二进制日志相关的服务器变量和配置说明:

sql_log_bin=ON | OFF  # 是否记录二进制日志,默认ON,支持动态修改,系统变量,而非服务器选项

log_bin=/PATH/BIN_LOG_FILE  # 指定文件位置,默认OFF,表示不启用二进制日志功能,上述两项都开启才可以生效

binlog_format=STATEMENT | ROW | MIXED  # 二进制日志记录的格式,上面由说明详细;生产中建议用ROW的

max_binlog_size=1073741824  # 单个二进制日志文件的最大限制,到达最大值会自动生成新的二进制文件,并备份旧的,默认为1G,大小不一定精确

binlog_cache_size=4m  # 此变量确定在每次事务中保存二进制日志更改记录的缓存的大小(每次连接)

max_binlog_cache_size=512m  # 限制用于缓存多事务查询的字节大小

sync_binlog=1 | 0  # 设定是否启动二进制日志即时同步磁盘功能,默认0,由操作系统负责同步日志到磁盘

expire_logs_days=N  # 二进制日志可以自动删除的天数,默认为0,即不自动删除

5.4)查看当前二进制文件使用

MariaDB [(none)]> show master logs;
+--------------------+-----------+
| Log_name           | File_size |
+--------------------+-----------+
| mysql-bin .000001  |       330 |
+--------------------+-----------+
1 row in set (0.000 sec)MariaDB [(none)]> 

5.5)更新使用二进制文件

MariaDB [(none)]> flush logs;
Query OK, 0 rows affected (0.003 sec)MariaDB [(none)]> show master logs;
+--------------------+-----------+
| Log_name           | File_size |
+--------------------+-----------+
| mysql-bin .000001  |       379 |
| mysql-bin .000002  |       375 |
+--------------------+-----------+
2 rows in set (0.000 sec)MariaDB [(none)]>

5.6)mysqlbinlog:二进制日志客服端命令工具,支持离线查看二进制文件

mysqlbinlog /data/mysqlbinlog/mysql-bin.000001
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#210424 21:21:24 server id 1  end_log_pos 256 CRC32 0x3312b0c1  Start: binlog v 4, server v 10.3.27-MariaDB-log created 210424 21:21:24 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
VBuEYA8BAAAA/AAAAAABAAABAAQAMTAuMy4yNy1NYXJpYURCLWxvZwAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABUG4RgEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAEEwQADQgICAoKCgHBsBIz
'/*!*/;
# at 256
#210424 21:21:24 server id 1  end_log_pos 285 CRC32 0x4a7f7e74  Gtid list []
# at 285
#210424 21:21:24 server id 1  end_log_pos 328 CRC32 0x4e04bf61  Binlog checkpoint mysql-bin.000001
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

6、中续日志:reley log,在主从复制架构中,从服务器用于保存从主服务器的二进制日志中读取的事件

三、备份和恢复

注意:二进制日志文件不应该与数据文件放在同一磁盘上

1、为什么要备份:灾难恢复(硬件故障、软件故障、自然灾害、黑客攻击、误操作测试等数据丢失场景)

2、备份类型

(1)完全备份,部分备份

(1.1)完全备份:整个数据集

(1.2)部分备份:只备份数据子集,如部分库或表

(2)完全备份、增量备份、差异备份

(2.1)增量备份:仅备份最近一次完全备份或增量备份(如果存在增量)以来的变化的数据,备份较快,还原复杂。

(2.2)差异备份:仅备份最近一次完全备份以来变化的数据,备份较慢,还原简单

(3)冷、温、热备份

(3.1)冷备:读、写操作均不可进行,数据库停止服务

(3.2)温备:读操作可执行,但写操作不可执行

(3.3)热备:读、写操作均可执行

MyISAM:温备,不支持热备

InnoDB:都支持

(4)物理和逻辑备份

(4.1)物理备份:直接复制数据文件进行备份,与存储引擎有关,占用空间较大,速度快

(4.2) 逻辑备份:从数据库中“导出”数据另存而进行的备份,与存储引擎无关,占用空间较小,速度慢,可能丢失精度

3、备份什么

(1)数据

(2)二进制日志、InnoDB的事务日志

(3)用户账号、权限设置、程序代码(存储过程、触发器、事件调度器)

(4)服务器的配置文件

4、备份注意要点

(1)能容忍最多丢失多少数据

(2)备份产生的负载

(3)备份过程的时长

(4)温备的持锁多久

(5)恢复数据需要在多长时间内完成

(6)需要备份和恢复哪些数据

5、还原要点

(1)做还原测试,用于测试备份的可用性

(2)还原演练,写成规范的技术文档

6、备份工具

(1)cp,tar等复制归档工具:物理备份工具,适用所有存储引擎,只支持冷备,完全和部分备份

(2)LVM的快照:先加读锁,做完快照后解锁,几乎热备,借助文件系统工具进行备份

(3)mysqldump:逻辑备份工具,适用所用存储引擎,对MyISAM存储引擎进行温备,支持完全或部分备份,对InnoDB存储引擎支持热备,结合binlog的增量备份

(4)xtrabackup:由Percona提供支持对InnoDB做热备(物理备份)的工具,支持完全备份、增量备份

(5)MariaDB Backup:从MariaDB 10.1.26开始集成,基于Percona XtraBackup 2.3.8实现的

(6)mysqlbackup:热备份,MySQL Enterprise Edition 组件

(7)mysqlhotcopy:PERL语言实现,几乎冷备,仅适用于MyISAM存储引擎,使用LOCK TABLES、FLUSH TABLES和cp或者scp来快速备份数据库

7、生产环境实战备份策略

(1)InnoDB建议备份策略

mysqldump -uroot -p -A -F -E -R --tiggers --single-transaction --master-data=1 --flush-privileges --default-character-set=utf8 --hex-blob > backup.sql

(2)MyISAM建立备份策略

mysqldump -uroot -p -A -F -E -R -x --tiggers --master-data=1 --flush-privileges --default-character-set=utf8 --hex-blob > backup.sql

四、xtrabackup实现全量+增量+binlog恢复库

1、xtrabackup的特点

1)备份还原过程快速、可靠

2)备份过程不会打断正在执行的事务

3)能过基于压缩等功能节约磁盘空间和流量

4)自动实现备份检验

5)开源、免费

2、xtrabackup2.2版本说明

1)xtrabackup是用来备份InnoDB表的,不能备份非InnoDB表的,和MySQL server没有交互

2)innobackupex脚本用来备份非InnoDB表,同时会调佣xtrabackup命令来备份InnoDB表,还会和MySQL server发送命令进行交互,如全局读锁(FTWRL)、获取位点(SHOW SLAVE STATUS)等。即innobackupex是在xtrabackup之上做了一层封装实现的。

3、xtrabackup2.4版本说明

xtrabackup相比之前的2.1有了比较大的变化:innobackupex功能全部集成到xtrabackup里面,只有一个binary程序,另外为了兼容考虑,innobackupex作为xtrabackup的软链接,即xtrabackup现在支持非InnoDB表备份,并且innobackupex在下一版本中移除,建议通过xtrabackup替换innobackupex。

4、xtrabackup备份过程

5、备份生成的相关文件

使用 innobackupex备份时,其会调用xtrabackup备份所有的InnoDB表,复制所有关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息相关的文件。这些文件会被保存至一个以时间命名的目录中,在备份时,innobackupex还会在备份目录中创建如下文件:

1)xtrabackup_info:文本文件,innobackupex工具执行时的相关信息,包括版本,备份选项,备份时长,备份LSN(log sequence number日志序列号),BINLOG的位置。

2)xtrabackup_checkpoints:文本文件,备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN范围信息,每个InnoDB(通常为16K大小)都会包含一个日志序列号LSN。LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的。

3)xtrabackup_binlog_info:文本文件,MySQL服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置,可利用实现基于binlog的恢复。

4)backup-my.cnf:文本文件,备份命令用到的配置选项信息。

5)xtrabackup_logfile:备份生成的二进制日志文件。

6、xtrabackup用法

(1)xtrabackup工具备份和还原,需要三步实现

1)备份:对数据库做完全或增量备份

2)预准备:还原前,对备份的数据,整理至一个临时目录

3)还原:将整理好的数据,复制回数据库目录中

(2)xtrabackup选项说明:

--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

(1)全量备份

xtrabackup -uroot -ppasswd --backup --traget-dir=/backup/20210425_base

(2)增量备份

xtrabackup -uroot -ppasswd --backup --traget-dir=/backup/20210425_incl --incremental-basedir=/backup/20210425_base

(3)差异备份

xtrabackup -uroot -ppasswd --backup --traget-dir=/backup/20210425_inc2 --incremental-basedir=/backup/20210425_inc1

(3)binlog恢复库

1、关闭mysql:systemctl stop mysqld

2、再删掉mysql数据目录下的数据文件,避免出现错误

3、先对备份做一个prepare,再使用命令进行还原

1)预准备完成备份,加选项 --apply-log-only 阻止回滚未完成的事务,如果后面没有增量或者差异备份的,不需要加选项

xtrabackup --prepare --apply-log-only --target-dir=/backup/20210425_base

2)合并第一次增量备份到完全备份目录上,也需要加选项 --apply-log-only

xtrabackup --prepare --apply-log-only --target-dir=/backup/20210425_base --incremental-dir=/backup/20210425_incl

3)合并第二次增量备份到完全备份目录上, 最后一次还原不需要加选项 --apply-log-only

xtrabackup --prepare --target-dir=/backup/20210425_base --incremental-dir=/backup/20210425_inc2# 对于只备份单个库的情况,不应该使用上面的操作,而应该使用复制命令去操作
scp -r /backup/20210425_base/* /var/lib/mysql/

4、复制到数据库目录中

xtrabackup --copy-back --target-dir=/backup/20210425_base

5、修改属性:chown mysql:mysql -R /var/lib/mysql

6、启动MySQL服务:systemctl start mysqld

7、把binlog执行的日志拿出来:

cat /backup/20210425_inc2/xtrabackup_binlog_info
centos8-bin.000002 1234
mysqlbinlog /backup/centos8-bin.000002 --start-position=1234 > /backup/bin_log.sql

8、到MySQL命令行里执行数据导入:

set sql_log_bin=off;
source /backup/bin_log.sql;
set sql_log_bin=on;

五、主从复制及主主复制的实现

1、主从复制架构原理

  • 主节点:

dump Thread:为每个Slave的 I/O Thread 启动一个dump线程,用于向其发送binary log events

  • 从节点:

I/O Thread:向master请求二进制日志事件,并保存于中续日志中

SQL Thread:从中续日志中读取日志事件,在本地完成重放

  • 跟复制功能相关的文件:

master.info:用于保存slave连接至master时的相关信息,例如账号、密码、服务器地址等

relay-log.info:保存在当前slave节点上已经复制的当前二进制日志和本地 relay log日志的对应关系

mariadb-relay-bin.00000*:中续日志,保存从主节点复制过来的二进制日志,本质就是二进制日志文件

1)服务性能扩展方式

  • Scale Up,向上扩展,垂直扩展
  • Scale Out,向外扩展,横向扩展

2)MySQL的扩展

  • 读写分离
  • 复制,每个节点都有相同的数据集,向外扩展,基于二进制日志的单向复制

3)复制的功能

  • 数据分布
  • 负载均衡读
  • 备份
  • 高可用和故障切换
  • MySQL升级测试

4)复制架构(一主一从复制架构)

5)一主多从复制架构

 6)主从复制特点

  • 异步复制:客服端性能良好
  • 主从数据不一致比较常见

7)各种复制架构

  • ——master/——slave
  • 一主多从
  • 从服务器还可以再有从服务器
  • master/master

8)实现主从复制配置

参考官网

https://mariadb.com/kb/en/library/setting-up-replication/

https://dev.mysql.com/doc/refman/8.0/en/replication-configuration.html

主MySQL配置

(1)开启二进制日志

[mysqld]
server-id=#
log-basename=master  # 可选项,设置datadir中日志名称,确保不依赖主机名
log-bin=mysql-bin

/etc/my.cnf中的配置文件里:server-id=1  # slave_id值同Master_id值一样,必须为1到2三十二次方减一之间的一个正整数值。并且,从服务器的ID必须与主服务器的ID不相同且从服务器必须大于主服务器。

192.168.64.11  为主数据库服务器

192.168.64.12  为从数据库服务器

(2)在192.168.64.11中创建一个192.168.64.12主机中可以登录的MySQL用户

用户:slave

密码:slave

MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO 'slave'@'192.168.64.12' IDENTIFIED BY 'slave';
Query OK, 0 rows affected (0.006 sec)MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.000 sec)MariaDB [(none)]>

(3)查看192.168.64.11 MySQL服务器二进制文件名与位置

MariaDB [(none)]> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      891 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.000 sec)MariaDB [(none)]>

从MySQL配置

启动中续日志

[mysqld]
server-id=#  # 为当前节点设置一个全局唯一的ID号,必须大于主节点ID号
log-bin
read_only=NO  # 设置数据库只读,针对supper user无效
relay_log=relay-log  # relay log的文件路径,默认值hostname-relay-bin
relay_log_index=relay-log.index  # 默认值hostname-relay-bin.index

(1)配置连接到主MySQL的信息

MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.64.11',
MASTER_USER='slave',
MASTER_PASSWORD='slave',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=891;Query OK, 0 rows affected (0.005 sec)MariaDB [(none)]> 

(2)开始复制

MariaDB [(none)]> START SLAVE;
Query OK, 0 rows affected (0.002 sec)MariaDB [(none)]> 

(3)查看主从复制是否配置成功

MariaDB [(none)]> SHOW SLAVE STATUS\G
*************************** 1. row ***************************Slave_IO_State: Connecting to masterMaster_Host: 192.168.64.11Master_User: slaveMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 891Relay_Log_File: mariadb-relay-bin.000001Relay_Log_Pos: 4Relay_Master_Log_File: mysql-bin.000001Slave_IO_Running: yesSlave_SQL_Running: Yes

在主节点上查看状态信息

show processlist;
\s

级联复制

在从的服务器后面再添加一个从的节点

2、主主复制的实现

(1)在主从复制的基础上增加配置

auto_increment_increment=2   #步进值auto_imcrement。一般有n台主MySQL就填n

auto_increment_offset=1   #起始值。一般填第n台主MySQL。此时为第一台主MySQL

并且重启服务器

(2)从MySQL配置

创建用户

MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO 'slave'@'192.168.64.11' IDENTIFIED BY 'slave';
Query OK, 0 rows affected (0.006 sec)MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.000 sec)MariaDB [(none)]>

查看二进制名和位置

MariaDB [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      891 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.000 sec)MariaDB [(none)]>

在192.168.64.11中执行:

MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.64.12', MASTER_USER='slave', MASTER_PASSWORD='slave', MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=891;

(3)分别开启复制:start slave;

(4)分别查看主从复制是否配置成功:SHOW SLAVE STATUS\G

当主从复制发生故障时,跳过错误事件

stop slave;
set global sql_slave_skip_counter=1;  # 在从节点上执行,跳过一个错误事件
start slave;

六、MySQL复制过滤器(主从架构)

解析:让从节点仅复制指定的数据库,或指定数据库的指定表,但也存在着确定,跨服将不记录,比如:在db4库上执行添加db3的表:create table db3.t3(id int);

1、复制过滤器两种实现方式:

(1)服务器选项:主服务器仅向二进制日志中记录与特定数据库相关的事件

注意:此方法存在的问题较大:基于二进制还原将无法实现,不建议使用

优点:只需要在主节点添加一次即可

注意:此项和binlog_format相关

参考:https://mariadb.com/kb/en/library/mysqld-options/#-binlog-ignore-db

vim /etc/my.cnf
binlog-do-db=db1  # 数据库白名单列表,不支持同时指定多个值,如果想实现多个数据库需多行配置
binlog-do-db=db2
binlog-do-db=db3# 数据库黑名单列表,不支持同时指定多个值,如果想实现多个数据库需多行配置,跟白名单不能同时使用
binlog-ignore-db=db1

(2)从服务器SQL_THREAD在relay log中的事件时,仅读取与特定数据库或特定表相关的事件并应用于本地

注意:此方法存在的问题较小:会造成网络及磁盘IO浪费,还需要在所有从节点上都要配置

优点:不影响二进制备份还原

vim /etc/my.cnf
replicate_do_db='db1,db2,db3'   # 指定复制库的白名单,变量可以指定多个,用英文逗号(,)分开
replicate_ignore_db=db1         # 指定复制库的黑名单,不能跟白名单同时使用
replicate_do_table=table        # 指定复制表的白名单
replicate_ignore_table=table    # 指定复制表的黑名单
replicate_wild_do_table=foo%.bar%   # 支持通配符
replicate_wild_ignore_table=

1--MySQL基础知识内容相关推荐

  1. MySQL工作中的实际用_总结工作中经常用到的mysql基础知识

    总结工作中经常用到的mysql基础知识 发布时间:2020-06-08 11:27:30 来源:51CTO 阅读:217 作者:三月 本文主要给大家介绍工作中经常用到的mysql基础知识,文章内容都是 ...

  2. MySQL基础知识-MySQL概述安装,单表增删改查,函数,约束,多表查询,事物

    MySQL基础知识-MySQL概述安装,单表增删改查,函数,约束,多表查询,事物 前言 1.MySQL概述 1.1数据库相关概念 1.2MySQL数据库 1.2.1版本 1.2.2下载 1.2.3安装 ...

  3. 快速学习mysql_快速学习MySQL基础知识

    这篇文章主要梳理了 SQL 的基础用法,会涉及到以下方面内容: SQL大小写的规范 数据库的类型以及适用场景 SELECT 的执行过程 WHERE 使用规范 MySQL 中常见函数 子查询分类 如何选 ...

  4. mysql基础知识(二)

    这一篇是第二部分,要查看第一部分,请查看这个链接 mysql基础知识(一) DQL语言 1.1简单的单表查询 查询表的通用格式:select [distinct] [*] [列名1,列名] from ...

  5. mysql基础知识(一)

    mysql是主流的关系型数据库管理系统(RDBMS---relation database management system),操作是需要用SQL(Structured Query Language ...

  6. 【MySQL基础知识】查询、过滤数据关键字

    MySQL基础知识 一.检索数据 1. SELECT select是使用最广泛的检索数据的语句. 检索要查的表的所有列: select * from (表名称)... 检索要查的表的某一列或多列: s ...

  7. MySQL基础知识之增删改查

    MySQL基础知识之增删改查 MySQL基本语法: 1.创建库:create database 库名: 创建带编码格式的库:create database 库名 character set 编码格式: ...

  8. linux增删查改语句,mysql基础知识之增删查改使用介绍

    mysql基础知识之增删查改使用介绍 本文主要介绍mysql常用的SELECT.INSERT.UPDATE.DELETE语句的使用,数据库的安装这里不做介绍,并且事先已经准备好相关数据. 本文中使用的 ...

  9. MySql基础知识【一】

    Mysql基础知识 1. MySql是什么 2. 数据库设计的三大范式 2.1. 第一范式 2.2. 第二范式 2.3. 第三范式 3. Binlog的三种模式 3.1 Statement模式(默认) ...

  10. 2.MySQL 基础知识

    文章目录 MySQL 基础知识 知识点一 : MySQL命令行常用命令 知识点二 : 持久化 相关概念 知识点三 : 数据库 相关概念 知识点四 : DB 和 DBMS 关系图示 知识点五 : MyS ...

最新文章

  1. 聚类Introducion
  2. 外部中断0——51程序
  3. 同时遍历多个dataframe_Java面试-容器的遍历
  4. leetcode1029. 两地调度(贪心算法)
  5. 史上最全企业数据产品选型对比(含数仓、报表、BI、中台、数据治理)
  6. 思科警告:IOS 路由器中含有多个严重缺陷,可导致“系统完全受陷”
  7. c# Dictionary 中Keys.ToArray方法的细节测试
  8. Android逆向之静态分析
  9. 2014计算机二级办公软件高级应用技术,计算机二级办公软件高级应用技术跟ms office一级考试的内容是不是一样的...
  10. 不确定度在线计算_气相色谱质谱法快速测定毒死蜱、联苯菊酯不确定度评定
  11. python unpack java,Java中的python struct.unpack - java
  12. 【综述】(MIT博士)林达华老师-概率模型与计算机视觉”
  13. Duplicate keys detected: ‘gggggg‘. This may cause an update error.的解决办法
  14. 苹果主题商店_小米怕被苹果找茬,开始下架相关IOS主题了!
  15. 关于QT源代码文件的归类
  16. jmeter-----使用
  17. 北美独立战争: 美国人编出来的神话
  18. html跳转页面 url不变,实现页面的跳转后,浏览器的地址栏不变
  19. 成都java培训,尽在传智播客成都中心
  20. 第 46 届 ICPC 国际大学生程序设计竞赛亚洲区域赛(上海)DEGHI

热门文章

  1. Hibernate学习-14:实体之间的关系及其配置,级联操作
  2. 【其它】Mac配置输入法切换快捷键
  3. Redis 面试面面观
  4. 在ie edge中消除默认出现的密码框小眼睛标志
  5. RuntimeError: iter() is only supported inside of tf.function or when eager execution is enabled.
  6. DDD(Domain-Driven Design 领域驱动设计) 与产品设计
  7. 打破思维断层之KMP分析
  8. 熊猫的python小课_老熊的三分地-Oracle及数据恢复
  9. 阿里云视频点播(上传视频)服务最新版本使用方法(解决部分依赖无法下载或不存在问题)
  10. xx-Pixiv Spider