SHOW PROCESSLIST
仅显示当前用户和会话的进程列表。
当前用户有没有办法列出所有当前打开的会话的所有进程?
ALTER TABLE ... ADD COLUMN
我对DDL 语句有疑问。
在带有 MariaDB v10.2 的 Amazon RDS 实例上,我注意到INSERT
语句已完成,并且行已正确插入表中(通过 验证SELECT
),然后ALTER TABLE ... ADD COLUMN
表中的 a 完成。
执行写入的任何 DML 语句不应该在ALTER TABLE
操作完成之前排队吗?
我发布这个问题是因为有人要求我执行一些测试,以验证是否可以ALTER TABLE ... ADD COLUMN
在工作时间在实时生产数据库上、在频繁使用的数据库上、在具有数百万行的表上运行——我觉得很不明智。即使ALTER TABLE
没有在表上加锁,它也必须等到任何连接不再使用表(由于连接放置了元数据锁),这可能会在很久以后发生。
编辑:显然这个评价太悲观了。我一直在做一些测试,mysqlslap
在表上执行繁重的操作(INSERT
, UPDATE
,DELETE
语句和SELECT
语句LIKE
避免在ALTER TABLE ... ADD COLUMN
运行时在 150 个模拟并发连接上使用索引;分析显示元数据锁,但等待时间很短(每个 1 秒),表更改在大约 30 分钟内完成,而没有运行 SQL 语句则需要 10 分钟。虽然这很令人满意,但另一方面,我想知道假设 DDL 语句是非阻塞的是否安全。
(可能值得注意的是 InnoDB 上有一个InstantADD COLUMN
功能,它允许向表中即时添加列(在特定约束下),但它在 v10.3.2 之前不可用。)
pt-duplicate-key-checker
这是搜索冗余索引的 Percona 工具的输出片段:
# Key myidx ends with a prefix of the clustered index
# Key definitions:
# KEY `myidx` (`bar`,`foo`)
# PRIMARY KEY (`foo`),
# Column types:
# `bar` mediumint(8) unsigned not null default '0'
# `foo` mediumint(8) unsigned not null auto_increment
# To shorten this duplicate clustered index, execute:
ALTER TABLE `mydb`.`mytable` DROP INDEX `myidx`, ADD INDEX `myidx` (`bar`);
为什么该工具会提示这个?原来的复合索引就不能用了吗?
据我了解,bar
给定 PK 上的索引值得删除(bar,foo)
,但这里并非如此。
我正在审核一个现成的电子商务应用程序使用的 MySQL 数据库的模式,我发现这是输出SHOW CREATE TABLE thistable
:
CREATE TABLE `thistable`
(
`case_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`company_id` int(11) NOT NULL DEFAULT '0',
(...)
`timestamp` int(11) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`case_id`),
KEY `idx_case_id` (`case_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=21688281 DEFAULT CHARSET=utf8
它显式地在主键上添加索引。
这是数据库设计者的失误,还是真的有原因?
值得注意的是,这张表起源于 MyISAM。
在 MySQL 5.6 服务器上,该mysql.user
表包含一个主机名为空 ( 'jdoe'@''
) 的用户。这意味着什么?
我正在管理一个电子商务站点,该站点使用在 MySQL 5.6 上运行的流行在线购物车软件。昨天我注意到SHOW PROCESSLIST
报告说 1000 个查询中有 990 个正在等待查询缓存锁定:
mysql> show processlist;
+----------+------------+---------------------+-------------+---------+------+--------------------------------+------------------------------------------------------------------------------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----------+------------+---------------------+-------------+---------+------+--------------------------------+------------------------------------------------------------------------------------------------------+
| 12224065 | sqluser | 10.13.13.13:21716 | mydatabase | Query | 0 | Waiting for query cache lock | SELECT `data` FROM mytable WHERE `foo` = 'bar' |
(...)
但是,Time 始终为 0,并且进程 ID 一直在变化。我的理解是查询等待表锁,但锁在不到一秒后被释放。
这是正常/可接受的行为,还是值得对查询缓存进行一些微调,也许完全删除它?
这个 MySQL 表让我困惑了一会儿:
mysql> desc quux;
+---------------------------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------------+-----------------------+------+-----+---------+----------------+
| foobar | int(11) | NO | | NULL | |
(...)
mysql> show create table quux;
(...)
`foobar` int(11) NOT NULL,
(...)
由于该foobar
字段从未使用 DEFAULT 子句创建,因此它会自动分配为 DEFAULT NULL。然而,乍一看,这似乎与它也被定义为 NOT NULL 的事实相矛盾。
然后我意识到这个模式旨在在foobar
添加新记录时强制插入一个值(和一个非 NULL 值)。
这是一种可以接受的方式,还是有更好的方式?
我们需要将数据库从 7-Gb mysqldump 文件恢复到 RDS Amazon 实例。完全恢复需要 3 到 4 个小时(可能是由于网络延迟,因为转储必须驻留在 EC2 上),这对我们来说太长了。作为参考,还原到本地 mysqld 需要不到 30 分钟。
是否有与亚马逊相关的解决方案可以让我们减少进口时间?
关于优化 mysqldump 恢复时间的问题之前有人问过,例如:
但是,这个问题是不同的,因为涉及到 RDS 实例,所以:
innodb_doublewrite
)不能更改以提高性能最近我不得不将一个 7 Gb MySQL 转储文件导入 MySQL 5.6 服务器。在具有 1 Gb RAM 的单核 CPU 上导入大约需要 7 个小时。
其他人在具有以下设置的 MySQL 服务器上测试了导入:
innodb_buffer_pool_size = 8G
query_cache_size = 300M
我对这些设置的相关性有点怀疑(是的,我什至认为设置这么大的查询缓存是不好的)。那会有什么不同吗?这些设置不是仅在查询数据库时使用,因此与导入无关吗?
如果是,应该设置哪些设置来加快大型转储文件的导入?
根据官方文档,这些值应该临时设置:
unique_checks = 0
foreign_key_checks = 0
我在这里读到它也应该设置
innodb_flush_log_at_trx_commit = 2
但我认为这不会有帮助,因为自动提交模式(每次插入都将日志刷新到磁盘)在 mysqldump 命令(--opt
选项)中已经默认禁用。
MySQL 允许在数据库名称中使用通配符,以允许用户仅对数据库的子集进行操作:
GRANT ALL PRIVILEGES ON `foobar%`.* TO 'user'@'%' IDENTIFIED BY 'somepassword';
有没有办法对 CREATE 授权做同样的事情,以允许(参见上面的示例)user
只创建名称以 开头的数据库foobar
?
否则说:CREATE 授予是全局的(即具有此权限的用户可以无限制地创建任何数据库)还是可以以某种方式受到限制?
我正在使用一个数据库监控系统,除其他数据外,它还显示了 SELECT 查询的以下值:
在这些查询中,哪些查询性能最差,因此应该首先优化?我会按重要性顺序说#2 和#4,但我也想听听对其他类型的评论。
该监控系统还将 SELECT 查询的总数显示为这五个值的总和。对于 SELECT,这些真的都是可能的、互斥的情况吗?
我不是在谈论特定的查询(我可以在慢查询日志中找到);我对上面列出的这 5 个中的查询类型更感兴趣。例如,全表扫描通常是一件坏事(除非我们正在处理小表,在这种情况下我们不会关心优化)。
我的另一个问题是这些类型是否可能重叠,因为监控系统显示的第 6 个值是这五个值的总和,如果这些类型不相互排斥(正如我们怀疑的那样),这就没有意义。
此查询打印mydatabase中表的大小(根据数据和索引):
SELECT table_name "Table name",
round(((data_length)/1024/1024),2) "Data size",
round(((index_length)/1024/1024),2) "Index size"
FROM information_schema.TABLES
WHERE table_schema="mydatabase" AND data_length>1000000
order by table_name INTO OUTFILE '/tmp/mydatabase_values'
FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';
大小以 Mb 为单位打印,并且只考虑大于 1Mb 的表。表格按字母顺序列出,输出保存到 CSV 文件中。
在不同的时间点运行这个查询显示——很明显——随着数据库中数据的变化而产生不同的结果。然而,就在最近几周,查询产生了相同的结果。这是否意味着数据库的大小没有太大变化(如您所见,四舍五入是在 10Kb 边界处完成的)还是我真的遗漏了什么?这个问题听起来可能很荒谬,但是视图中的视图是否INFORMATION_SCHEMA
始终包含最新的元数据?
注意:不,我不是每次都错误地读取同一个 CSV 文件。
编辑:所有表都是 InnoDB,并且innodb_file_per_table=1
.
在 MySQL 集群上,将 MySQL 数据库文件和 binlog 存储在不同的分区中是否有意义?
(这是关于同一个物理磁盘上的分区。如果它们在不同的物理磁盘上,答案是肯定的——所以允许并行读写。)
人们可能会认为,通过将 datadir 和 binlog dir 分隔在不同的分区上,如果一个被填满,另一个继续有空闲空间。但实际上这并不重要,因为这两个事件中的任何一个都会停止复制或完全停止 MySQL 服务器。另一方面,datadir 和 binlogs 的单个分区将允许它们共享可用的可用空间,从而为它们提供更多的扩展空间。
因此,共享分区似乎没有任何特别的缺点,但可能有一些优点。还有什么要考虑的吗?
我有一个 3 节点 Percona XtraDB 集群,根据mysqlcheck
,其中一些表已损坏(一些索引包含错误数量的条目):
mydb.mytable
Warning : InnoDB: Index 'foo' contains 1393929 entries, should be 1393918.
Warning : InnoDB: Index 'bar' contains 1393921 entries, should be 1393918.
error : Corrupt
OPTIMIZE TABLE
在集群上运行的最佳实践是什么?
我在没有用户的测试环境中做了一些实验,似乎OPTIMIZE TABLE
一个节点上的 an 不会自动将其效果传播到其他节点。这与该命令修改索引和表的存储空间,而不是其内容或定义的事实是一致的。
在每个节点的生产环境中运行命令,让它在下一个节点中运行之前完成,可能有什么缺点?
考虑到 MySQL(和 Percona XtraDB Cluster,据我所知)不支持分布式表锁,对用户会有什么影响?这会使集群处于不一致的状态吗?
我管理一个 Percona XtraDB 集群,该集群使用带有摆动连接的网络存储。我们会周期性地遇到高 iowait 崩溃并以只读方式重新挂载 fs。不幸的是,更换存储目前不是一种选择。
最近我注意到当运行 mysqldump 或 mysqlcheck 时,它们会使节点上的 MySQL 服务器崩溃,并出现错误mysqlcheck: Got error: 2013: Lost connection to MySQL server during query when executing 'CHECK TABLE ... '
以下是mysqld.log
崩溃期间的内容:
InnoDB: Error in pages 9479 and 9480 of index "PRIMARY" of table "foobar"."quux"
InnoDB: broken FIL_PAGE_NEXT or FIL_PAGE_PREV links
2015-09-28 14:39:45 7f015813b700 InnoDB: Page dump in ascii and hex (16384 bytes):
(...)
InnoDB: End of page dump
2015-09-28 14:39:45 7f015813b700 InnoDB: uncompressed page, stored checksum in field1 4038097986, calculated checksums for field1: crc32 2787032309, innodb 4038097986, none 3735928559, stored checksum in field2 1190336748, calculated checksums for field2: crc32 2787032309, innodb 1190336748, none 3735928559, page LSN 4 3652646491, low 4 bytes of LSN at page end 3652646491, page number (if stored to page already) 9479, space id (if created with >= MySQL-4.1.1 and stored already) 18
InnoDB: Page may be an index page where index id is 67
InnoDB: (index "PRIMARY" of table "foobar"."quux")
2015-09-28 14:39:45 7f015813b700 InnoDB: Page dump in ascii and hex (16384 bytes):
(...)
InnoDB: End of page dump
2015-09-28 14:39:46 7f015813b700 InnoDB: uncompressed page, stored checksum in field1 554678569, calculated checksums for field1: crc32 2178598661, innodb 554678569, none 3735928559, stored checksum in field2 1065260512, calculated checksums for field2: crc32 2178598661, innodb 1065260512, none 3735928559, page LSN 10 202985777, low 4 bytes of LSN at page end 202985777, page number (if stored to page already) 6792, space id (if created with >= MySQL-4.1.1 and stored already) 18
InnoDB: Page may be an index page where index id is 67
InnoDB: (index "PRIMARY" of table "foobar"."quux")
InnoDB: Corruption of an index tree: table "foobar"."quux", index "PRIMARY",
InnoDB: father ptr page no 55234, child page no 9479
PHYSICAL RECORD: n_fields 14; compact format; info bits 0
0: len 30; hex 34616434393538322d353232372d653863302d326466662d353461663639; asc 4ad49582-5227-e8c0-2dff-54af69; (total 36 bytes);
1: len 6; hex 000000000dd7; asc ;;
2: len 7; hex c8000001741ea1; asc t ;;
3: len 5; hex 99951259cb; asc Y ;;
4: len 5; hex 99951259cb; asc Y ;;
5: len 30; hex 62633965323864352d383865382d343466322d393337322d353339303931; asc bc9e28d5-88e8-44f2-9372-539091; (total 36 bytes);
6: len 30; hex 62633965323864352d383865382d343466322d393337322d353339303931; asc bc9e28d5-88e8-44f2-9372-539091; (total 36 bytes);
7: len 1; hex 80; asc ;;
8: len 30; hex 64356664666538352d656431652d346465362d383363612d616439663164; asc d5fdfe85-ed1e-4de6-83ca-ad9f1d; (total 36 bytes);
9: len 8; hex 436f6e7461637473; asc Contacts;;
10: len 4; hex 6c696e6b; asc link;;
11: len 30; hex 7b226f626a656374223a7b226e616d65223a224d72204a6f7264616e204e; asc {"object":{"name":"Mr John Hacker; (total 343 bytes);
12: len 4; hex 80000000; asc ;;
13: len 30; hex 7b226e616d65223a22222c22646f635f6f776e6572223a22222c22757365; asc {"name":"","doc_owner":"","use; (total 72 bytes);
n_owned: 0; heap_no: 2; next rec: 751
PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 30; hex 34616435616262302d303535662d333939612d613038652d353439396461; asc 4ad5abb0-055f-399a-a08e-5499da; (total 36 bytes);
1: len 4; hex 0000d7c2; asc ;;
n_owned: 0; heap_no: 277; next rec: 4688
InnoDB: You should dump + drop + reimport the table to fix the
InnoDB: corruption. If the crash happens at the database startup, see
InnoDB: http://dev.mysql.com/doc/refman/5.6/en/forcing-innodb-recovery.html about
InnoDB: forcing recovery. Then dump + drop + reimport.
2015-09-28 14:39:46 7f015813b700 InnoDB: Assertion failure in thread 139643749381888 in file btr0btr.cc line 1492
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.6/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.
12:39:46 UTC - mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed,
something is definitely wrong and this may fail.
Please help us make Percona XtraDB Cluster better by reporting any
bugs at https://bugs.launchpad.net/percona-xtradb-cluster
key_buffer_size=25165824
read_buffer_size=131072
max_used_connections=7
max_threads=202
thread_count=10
connection_count=5
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 105204 K bytes of memory
Hope that's ok; if not, decrease some variables in the equation.
Thread pointer: 0xf4de780
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 7f015813ad38 thread_stack 0x40000
/usr/sbin/mysqld(my_print_stacktrace+0x35)[0x8fa965]
/usr/sbin/mysqld(handle_fatal_signal+0x4b4)[0x665644]
/lib64/libpthread.so.0(+0xf710)[0x7f0185a25710]
/lib64/libc.so.6(gsignal+0x35)[0x7f0183e6b625]
/lib64/libc.so.6(abort+0x175)[0x7f0183e6ce05]
/usr/sbin/mysqld[0xa10d84]
/usr/sbin/mysqld[0xa16cc8]
/usr/sbin/mysqld[0x917920]
/usr/sbin/mysqld(_ZN7handler8ha_checkEP3THDP15st_ha_check_opt+0x6a)[0x5a422a]
/usr/sbin/mysqld[0x835fc3]
/usr/sbin/mysqld(_ZN19Sql_cmd_check_table7executeEP3THD+0xc2)[0x836cd2]
/usr/sbin/mysqld(_Z21mysql_execute_commandP3THD+0x33d5)[0x6ed235]
/usr/sbin/mysqld(_Z11mysql_parseP3THDPcjP12Parser_state+0x658)[0x6f0958]
/usr/sbin/mysqld[0x6f0acd]
/usr/sbin/mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0x19d5)[0x6f2de5]
/usr/sbin/mysqld(_Z10do_commandP3THD+0x22b)[0x6f42cb]
/usr/sbin/mysqld(_Z24do_handle_one_connectionP3THD+0x17f)[0x6bc52f]
/usr/sbin/mysqld(handle_one_connection+0x47)[0x6bc717]
/usr/sbin/mysqld(pfs_spawn_thread+0x12a)[0xaf611a]
/lib64/libpthread.so.0(+0x79d1)[0x7f0185a1d9d1]
/lib64/libc.so.6(clone+0x6d)[0x7f0183f218fd]
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (7efebc091d30): is an invalid pointer
Connection ID (thread ID): 2336
Status: NOT_KILLED
很明显,桌子foobar.quux
严重损坏。使用数据库的应用程序仍然有效(尽管性能有所降低),SELECT
语句也是如此。
mysqlcheck 工具不能用来修复它,所以我知道的解决方案是做 a SELECT * FROM quux INTO OUTFILE
,删除表,然后LOAD DATA INFILE
在下一个维护窗口期间做 a 。这种处理方式是否存在缺点,是否有其他选择来修复表格?
编辑:我重新启动了 MySQL 服务器,其值innodb_force_recovery
从 1 增加到 4,结果始终相同:
mysqldump 失败并出现错误mysqldump: Error 2013: Lost connection to MySQL server during query when dumping table quux at row: 156915
MySQL 命令SELECT * FROM quux INTO OUTFILE '/root/quux.sql';
在出现错误后不久失败ERROR 2013 (HY000): Lost connection to MySQL server during query
我要试试innodb_force_recovery=5
吗innodb_force_recovery=6
?可能有什么缺点?
在 MySQL 主从复制架构中,你如何检测是否有(错误的,因为这永远不应该发生!)从属服务器上的直接写入?
现在,我在从机上运行这个命令:
tcpdump tcp port 3306 and not host my_master_IP -A | grep -i -e INSERT -e UPDATE -e DELETE
其输出(如果有的话)意味着写入从机,这是不好的。
有更好的方法吗?
我运行 MySQLTuner 来验证 MySQL 数据库的配置,它报告了这个问题:
[!!] Maximum possible memory usage: 40.9G (1022% of installed RAM)
这些数字来自计算max_connections
乘以文件中的read_buffer_size
++ ,有效地给出了sort_buffer_size
40Gb 。 join_buffer_size
my.cnf
但是,服务器有 128Gb 的 RAM。看来 MySQL 只能看到 4Gb。
起初我以为这是因为64 位操作系统上的 MySQL 32 位二进制文件只能有效访问 4Gb 的 RAM。但是,MySQL 二进制文件和操作系统都是 64 位的:
root@box# isainfo -v
64-bit amd64 applications
pclmulqdq aes sse4.2 sse4.1 ssse3 popcnt tscp ahf cx16 sse3 sse2 sse
fxsr mmx cmov amd_sysc cx8 tsc fpu
32-bit i386 applications
pclmulqdq aes sse4.2 sse4.1 ssse3 popcnt tscp ahf cx16 sse3 sse2 sse
fxsr mmx cmov sep cx8 tsc fpu
root@box# uname -a
SunOS box 5.11 11.2 i86pc i386 i86pc
root@box# file /usr/local/bin/mysql
/usr/local/bin/mysql: ELF 64-bit LSB executable AMD64 Version 1 [SSE2 SSE FXSR CMOV FPU], dynamically linked, not stripped
并且进程可以访问多少内存没有限制:
root@box# ulimit -a
address space limit (kbytes) (-M) unlimited
core file size (blocks) (-c) unlimited
cpu time (seconds) (-t) unlimited
data size (kbytes) (-d) unlimited
file size (blocks) (-f) unlimited
locks (-x) not supported
locked address space (kbytes) (-l) not supported
message queue size (kbytes) (-q) not supported
nice (-e) not supported
nofile (-n) 256
nproc (-u) 29995
pipe buffer size (bytes) (-p) 5120
max memory size (kbytes) (-m) not supported
rtprio (-r) not supported
socket buffer size (bytes) (-b) 5120
sigpend (-i) 128
stack size (kbytes) (-s) 8192
swap size (kbytes) (-w) not supported
threads (-T) not supported
process size (kbytes) (-v) unlimited
还有另一种方法可以查看 MySQL 有效使用了多少内存吗?
(如果你问,shell 是 tcsh;由于权限不足,我无法标记帖子“tcsh”。)
我需要一个用户能够从机器 foobarhost,IP 10.11.12.13 登录我们的 MySQL 服务器 5.6。
因此我创建了一个用户'joe'@'foobarhost'
,但他无法登录。我必须创建一个用户'joe'@'10.11.12.13'
,这次工作正常。
我的问题:MySQL 如何处理有关用户的主机名和 IP 地址?
MySQL在检查匹配之前对用户表进行排序,使用 IP 地址和主机名作为要匹配的最具体的值。但是,文档没有指定优先级 - 主机名或 IP。MySQL 是否尝试解析主机名,如果失败,是否对 IP 执行检查?
用户表的推荐用法是什么:仅指定 IP 地址、主机名或两者都指定(如我在上面的示例中所做的那样)?