关于show tables命令的一场探险

本文探讨了MySQL中.show tables;命令如何通过检索.frm文件确定数据库中的表,并揭示了表信息存储位置及文件权限对表访问的影响。

已下是操作记录,在此先说结论

show tables命令更像是操作系统级的命令,通过找出所有.frm的文件,以确定该数据库中是否有该表。而至于.frm文件是否是表的结构文件,并不会去验证


mysql> desc test;

ERROR 1146 (42S02): Table 'wzy.test' doesn't exist




[root@localhost bak]# ls
Test.frm  Test.ibd
[root@localhost bak]# cp Test.frm ..
[root@localhost bak]# cp Test.ibd ..


[root@localhost wzy]# ls
bak  db.opt  test.frm  Test.frm  test.ibd  Test.ibd




mysql> use wzy
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
mysql> show tables;
+---------------+
| Tables_in_wzy |
+---------------+
| Test          |
| test          |
+---------------+
2 rows in set (0.00 sec)
我们在此看到两个表,可见只要有frm文件,就可以在库中看到表。

mysql> desc Test;
ERROR 1146 (42S02): Table 'wzy.test' doesn't exist
mysql> desc test;
ERROR 1146 (42S02): Table 'wzy.test' doesn't exist


这里是由于数据库启用lower_case_table_names=1,所有的sql都强制转换成小写,所以报错的都是test doesn't exist




mysql> use wzy
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
mysql> show tables;
+---------------+
| Tables_in_wzy |
+---------------+
| Test          |
| test          |
+---------------+
2 rows in set (0.00 sec)


mysql> desc Test;
ERROR 1017 (HY000): Can't find file: './wzy/Test.frm' (errno: 13 - Permission denied)
mysql> desc test;
ERROR 1146 (42S02): Table 'wzy.test' doesn't exist
mysql> quit
在这里lower_case_table_names=0,所有的sql大小写敏感,Test表之前是在大小写敏感时创建的,这个之后解释。



"uctest.frm" [New] 1L, 8C written
[root@localhost wzy]# ls

bak  db.opt  Test.frm  Test.ibd  uctest.frm

在这里创建了一个空的文件uctest.frm

[root@localhost wzy]# service mysql start
Starting MySQL. SUCCESS! 
[root@localhost wzy]# mysql -uroot -poracle
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 1
Server version: 5.6.25 MySQL Community Server (GPL)


Copyright (c) 2000, 2015, 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.


mysql> use wzy
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
mysql> show tables;
+---------------+
| Tables_in_wzy |
+---------------+
| Test          |
| uctest        |
+---------------+
2 rows in set (0.00 sec)
我们可以看到,在数据库中可以看到uctest。

mysql> desc Test;
ERROR 1017 (HY000): Can't find file: './wzy/Test.frm' (errno: 13 - Permission denied)
mysql> Ctrl-C -- exit!
Aborted
[root@localhost wzy]# exit
logout
我们最后来处理一下Permission denied的问题

Last login: Mon Aug 10 20:09:16 2015 from 192.168.40.1
[root@localhost ~]# cd /var/lib/mysql/
[root@localhost mysql]# cd wzy/
[root@localhost wzy]# ls
bak  db.opt  Test.frm  Test.ibd  uctest.frm
[root@localhost wzy]# ll
total 120
drwxr-xr-x. 2 root  root   4096 Aug 11 01:03 bak
-rw-rw----. 1 mysql mysql    65 Aug 10 21:35 db.opt
-rw-r-----. 1 root  root   8560 Aug 11 00:32 Test.frm
-rw-r-----. 1 root  root  98304 Aug 11 00:32 Test.ibd
-rw-r--r--. 1 root  root      8 Aug 11 01:07 uctest.frm
[root@localhost wzy]# chown mysql Test.frm 
[root@localhost wzy]# chown mysql Test.ibd 
[root@localhost wzy]# ls
bak  db.opt  Test.frm  Test.ibd  uctest.frm
[root@localhost wzy]# ll
total 120
drwxr-xr-x. 2 root  root   4096 Aug 11 01:03 bak
-rw-rw----. 1 mysql mysql    65 Aug 10 21:35 db.opt
-rw-r-----. 1 mysql root   8560 Aug 11 00:32 Test.frm
-rw-r-----. 1 mysql root  98304 Aug 11 00:32 Test.ibd
-rw-r--r--. 1 root  root      8 Aug 11 01:07 uctest.frm
[root@localhost wzy]# chown -g mysql Test.ibd 
chown: invalid option -- 'g'
Try `chown --help' for more information.
[root@localhost wzy]# chgrp mysql Test.ibd 
[root@localhost wzy]# chgrp mysql Test.frm 
[root@localhost wzy]# ll

drwxr-xr-x. 2 root  root   4096 Aug 11 01:03 bak
-rw-rw----. 1 mysql mysql    65 Aug 10 21:35 db.opt
-rw-r-----. 1 mysql mysql    8560 Aug 11 00:32 Test.frm
-rw-r-----. 1 mysql mysql  98304 Aug 11 00:32 Test.ibd
-rw-r--r--. 1 root  root      8 Aug 11 01:07 uctest.frm

使用chown与chgrp将用户属组转给mysql用户mysql组

[root@localhost wzy]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.6.25 MySQL Community Server (GPL)


Copyright (c) 2000, 2015, 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.


mysql> use wzy
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
mysql> show tables;
+---------------+
| Tables_in_wzy |
+---------------+
| Test          |
| uctest        |
+---------------+
2 rows in set (0.00 sec)


mysql> desc Test;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| col1  | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.03 sec)


mysql> 

这时已经正常只用这张Test表了。


实验比较混乱,再说下发现的东西,show tables命令应该是通过检索.frm文件来确定库中的表名,本身也不对frm文件进行校验,但是表的相关信息是有写到ibdata1中的,你直接移动.frm与.ibd文件并不能直接迁移文件。

<think>好的,用户在使用Docker时遇到了问题,具体是在执行`docker exec`运行`mysql show tables`命令时报错。我需要根据提供的引用资料和已有的知识来找到解决方案。 首先,用户的问题是如何正确使用`docker exec`命令来在MySQL容器中执行`show tables`命令。根据引用[3],进入MySQL容器的方法是使用`docker exec -it 容器ID bash`,然后登录MySQL。这说明用户可能需要先进入容器的bash环境,再执行MySQL命令。 接下来,用户可能直接在`docker exec`后面添加`mysql show tables`,这样可能没有正确连接到MySQL客户端。正确的做法应该是通过`mysql -u用户名 -p密码`来登录数据库,然后执行SQL语句。引用[4]中提到在容器内登录MySQL需要输入密码,并且可能需要修改密码或配置权限。 可能的错误原因包括: 1. 没有正确进入MySQL命令行,直接在容器内执行`show tables`而没有启动MySQL客户端。 2. 用户名或密码错误,导致认证失败。 3. 用户权限不足,无法访问特定数据库。 解决方案应分步骤:首先确认容器状态,然后进入MySQL命令行,再执行SQL命令。如果用户希望一行命令完成,需要正确拼接`mysql -e`参数。此外,可能需要处理密码中的特殊字符,使用单引号包裹命令。 还需要考虑是否需要指定数据库,因为`show tables`需要先选择数据库。例如,添加`-D 数据库名`参数。引用[4]中的步骤提到登录后修改密码和权限,这可能影响用户当前的登录方式,尤其是如果用户使用的是MySQL 8.0及以上版本,密码策略和身份验证插件可能有变化,导致连接问题。 总结步骤: 1. 确保容器正在运行。 2. 进入容器并启动MySQL客户端,输入密码后执行`show tables`。 3. 或者使用单行命令`docker exec 容器名 mysql -u root -p密码 -e "USE 数据库名; SHOW TABLES;"`。 4. 处理可能存在的权限问题,如引用[4]中提到的修改用户Host和刷新权限。 需要检查用户是否遗漏了指定数据库或密码错误,以及是否正确转义了特殊字符。此外,提醒用户关于MySQL 8.0的密码安全设置,可能需要更新身份验证方式。</think>### 分步解决方案 在使用 `docker exec` 运行 `mysql show tables` 时报错,通常是因为命令格式或执行环境不正确。以下是具体解决步骤: --- #### **1. 确认容器状态** 确保 MySQL 容器正在运行: ```bash docker ps | grep mysql ``` 如果容器未运行,先启动容器: ```bash docker start <容器名或ID> ``` --- #### **2. 正确进入 MySQL 命令行** 直接通过 `docker exec` 进入容器并登录 MySQL: ```bash docker exec -it <容器名或ID> mysql -u <用户名> -p ``` 输入密码后,再执行 `SHOW TABLES;`[^3]。 --- #### **3. 单行命令执行(推荐)** 如果希望直接通过 `docker exec` 执行 `SHOW TABLES`,需指定数据库名并拼接命令: ```bash docker exec <容器名或ID> mysql -u <用户名> -p<密码> -e "USE <数据库名>; SHOW TABLES;" ``` - `-p<密码>` 注意不要有空格(例如 `-proot` 对应密码 `root`)。 - 如果密码含特殊字符(如 `$`),用单引号包裹命令: ```bash docker exec <容器名> mysql -u root -p'your_password' -e "SHOW TABLES" <数据库名> ``` --- #### **4. 常见错误处理** - **权限问题** 如果报错 `Access denied`,检查用户权限或密码是否正确。可参考引用[4]的步骤修改密码或权限: 1. 进入容器后登录 MySQL: ```bash docker exec -it <容器名> mysql -u root -p ``` 2. 修改密码并刷新权限: ```sql ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '新密码'; FLUSH PRIVILEGES; ``` - **未选择数据库** 若未指定数据库,需在命令中添加 `USE <数据库名>` 或通过参数 `-D <数据库名>` 指定: ```bash docker exec <容器名> mysql -u root -p密码 -D <数据库名> -e "SHOW TABLES" ``` --- ### **总结** - **正确命令格式**:通过 `mysql -u -p -e` 拼接 SQL 语句,或先进入交互式环境再执行命令。 - **权限与密码**:确保用户名、密码正确,必要时更新权限[^4]。 - **指定数据库**:明确操作的目标数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值