如何更改MySQL数据目录?

186

是否可以将默认的MySQL数据目录更改为其他路径?我是否能够从旧位置访问数据库?


2
针对Windows系统,请查看此处:http://dba.stackexchange.com/questions/24403/change-existing-datadir-path/24437#24437?newreg=8ac58d6446484ed98c0c7fb695be3ef5 - Dr. Aaron Dishno
1
对于 Mac 用户,您只需要这个,并按照 @user1341296 的答案中的1-4步骤进行操作即可。 - shellbye
我知道这是一个老问题,但请具体说明操作系统,否则,人们会一年又一年地猜测,真是让人发疯啊 :) 从 macOS 到 Microsoft Windows,再到各种 Linux 版本和 FreeBSD 等等。谢谢。 - undefined
28个回答

322
  1. 使用以下命令停止MySQL:

    sudo /etc/init.d/mysql stop
    
  2. 使用以下命令复制现有数据目录(默认位于 /var/lib/mysql):

  3. sudo cp -R -p /var/lib/mysql /newpath
    
  4. 使用以下命令编辑MySQL配置文件:

  5. sudo gedit /etc/mysql/my.cnf   # or perhaps /etc/mysql/mysql.conf.d/mysqld.cnf
    
  6. 找到datadir的条目,将路径(应该是/var/lib/mysql)更改为新的数据目录。

  7. 在终端中输入以下命令:

  8. sudo gedit /etc/apparmor.d/usr.sbin.mysqld
    
  9. 查找以/var/lib/mysql开头的行。在这些行中,将/var/lib/mysql更改为新路径。

  10. 保存并关闭文件。

  11. 使用命令重新启动AppArmor配置文件:

  12. sudo /etc/init.d/apparmor reload
    
  13. 使用以下命令重新启动MySQL:

    sudo /etc/init.d/mysql restart
    
  14. 现在登录 MySQL,您可以访问之前拥有的同样的数据库。


39
以上在Ubuntu 12.04(Precise)对我无法解决问题。 我发现需要编辑文件/etc/apparmor.d/tunables/alias,包括一行“alias /var/lib/mysql/ -> /newpath/”,将其放置后,不需要更改任何其他AppArmor文件。 在使用“/etc/init.d/apparmor restart”重启AppArmor和“restart mysql”重启MySQL之后立即生效。 - mak
5
Apparmor对于CentOS不相关,取而代之的是SELinux。可以在此处阅读如何禁用或管理https://blogs.oracle.com/jsmyth/entry/selinux_and_mysql。 - Noam
15
请注意,在mak的版本中(这是必要的),不要忘记在行末添加逗号:alias /var/lib/mysql/ -> /newpath/, - Michael
4
强调Michel上面的评论有多重要:记得加上尾逗号,可以省下一些神经元。抱歉用了大写字母。 - alx
3
对我没用。当我尝试重新启动mysqld时,我得到了“mysql.service作业失败”的错误信息。请查看'systemctl status mysql.service'和'journalctl -xn'获取详细信息,错误原因是磁盘已满。虽然磁盘上有500GB的可用空间... - Frank H.
显示剩余19条评论

25

快速简单的操作:

# Create new directory for MySQL data
mkdir /new/dir/for/mysql

# Set ownership of new directory to match existing one
chown --reference=/var/lib/mysql /new/dir/for/mysql

# Set permissions on new directory to match existing one
chmod --reference=/var/lib/mysql /new/dir/for/mysql

# Stop MySQL before copying over files
service mysql stop

# Copy all files in default directory, to new one, retaining perms (-p)
cp -rp /var/lib/mysql/* /new/dir/for/mysql/

编辑/etc/my.cnf文件,在 [mysqld] 下面添加这一行:

datadir=/new/dir/for/mysql/

如果您正在使用CageFS(无论是否使用CloudLinux)并且想要更改MySQL目录,则必须将新目录添加到此文件中:

/etc/cagefs/cagefs.mp

然后运行这个命令:

cagefsctl --remount-all

1
很高兴听到这个消息 :P - sMyles
非常感谢,如果您想像我一样完全编写脚本,可以使用以下命令:sed -i 's|datadir=/var/lib/mysql|datadir=/data/var/lib/mysql|g' /etc/my.cnf - berimbolo
这对我没用。我尝试了这个方法和许多其他不同的替代方案。当user3338098说这是唯一可行的方法时,我得出了相同的结论: https://serverfault.com/questions/503887/cant-start-mysql-after-changing-directories/733998#733998 - Volksman
@Volksman,链接中所说的只是他不得不卸载并重新安装...很有可能你们两个都有一些其他特定于服务器的问题,因为MySQL和MariaDB都支持datadir配置,并且我最近在另一台服务器上进行了此操作(6个月前),没有出现任何问题。 - sMyles
2
我在你所指定的位置找不到 my.cnf 文件,但是在这里找到了:/etc/mysql/mysql.conf.d/mysqld.cnf - Edenshaw
显示剩余2条评论

22

你需要将当前数据复制到新目录,并更改 MySQL 的 my.cnf

[mysqld]
datadir=/your/new/dir/
tmpdir=/your/new/temp/

在服务器未运行的情况下,你必须复制数据库。


1
@MySQL DBA:如果您使用一些ln -s静态符号链接,那么这不会使它变得更好吗? - RageZ
1
我对这个命令的使用有点困惑。如我之前所述,我想在新目录中创建新数据库。使用符号链接是否可行? - MySQL DBA
1
你可以创建一个新目录,使用符号链接将文件显示在新目录中,并更改你的 my.cnf - RageZ
@MySQL 数据库查询:这意味着那几乎是不可能的。 - RageZ
2
因为它在 http://serverfault.com/a/733998/279553 中的详细信息不起作用,所以被投下反对票。 - user3338098
显示剩余3条评论

18

如果您是Windows用户,来到这里寻找解决方案却发现所有答案都是针对Linux用户的,请不要失望!我不会让你像我一样浪费时间。

解决方案之前先废话几句:

MySQL使用一个数据目录来存储您创建的不同数据库的数据。最终,它必须以文件的形式存储它们,并添加一些应用程序和文件格式上的操作,以确保您在数据库课程中所学的数据库承诺得以保持完整。

现在,您想确保有足够的空间来存储您将来可能创建的大型数据库,因此您想:嘿!我想将其放入另一个可用空间更多的驱动器中。

那么,您可以按照以下步骤操作。

步骤1:停止MySQL服务。

  Window Key + R - will open Run
  servies.msc    - will open services manager
  Locate MySQL80 (80 is for version 8.0, look for the one you've).
  Stop it.       (Right click, Stop)

步骤 - 2:查找当前数据目录

 Goto C:\ProgramData\MySQL\MySQL Server 8.0

默认情况下,这里应该有一个名为Data的文件夹,这是MySQL在默认设置中使用的文件夹(前提是他们没有找到其他更好的位置),但我们来检查一下。

找到my.ini文件,应该就在那里。

用编辑器(例如Notepad ++)打开它。

进行CTRL + F以在文件中查找datadir

无论此处提到什么,都是MySQL当前正在使用的数据目录的实际位置。这就是您想要更改的内容。

第三步:将其替换为新数据目录。

假设您希望新数据目录位于W:__MySQL_Data。让我们将my.ini文件中的datadir值更改为此值。保留先前的值作为注释,这样您就不必记住它。

 # Path to the database root
 # datadir=C:/ProgramData/MySQL/MySQL Server 8.0/Data
   datadir=W:/__MySQL_Data

现在使用xcopy将默认的datadir复制到W:\。启动命令提示符(Windows+R,cmd,Enter)

 >> xcopy "\C:\ProgramData\MySQL\MySQL Server 8.0" "W:\" /E /H /K /O /X

将复制的文件夹重命名为你修改后的新datadir值。这里是:W:/__MySQL_Data

为什么不只是简单地复制呢?因为那样不够酷!这可以帮助你避免在复制的文件夹上失去权限,所以当你重新启动MySQL80时,它就不会出现愚蠢的错误:"本地计算机上的MySQL80服务已经启动,然后停止了。如果某些服务未被其他服务或程序使用,则自动停止一些服务。" - 来源:微软

步骤-4:重新启动服务

 Well, go back to the Services Manager to Start again, 
 "MySQL80" that you stopped, to restart it again.

步骤-5:完成!现在回到工作中!!


2
谢谢,这很有帮助。但是请注意:my.ini 文件不可由普通用户进行写入,除非您更改其权限。另外,ProgramData 是一个隐藏文件夹,因此您需要更改资源管理器文件夹设置才能看到它。 - JonP

17

首先,您应该停止 mysql 服务器。例如:

# /etc/init.d/mysql stop

之后,您应该通过以下方式将旧数据目录(例如/var/lib/mysql)以及权限复制到新目录:

# cp -R -p /var/lib/mysql /new/data/dir

现在你可以在/etc/mysql/my.cnf中更改数据并重新启动服务器。

# /etc/init.d/mysql restart

5
因为它在 http://serverfault.com/a/733998/279553 中的详细说明无法正常工作而被投下反对票。 - user3338098

8
如果你和我一样使用debian,并且想要将mysql目录移动到你的home目录或者在/home/...路径下的其他位置,解决方案如下:
  • 通过命令"sudo service mysql stop"停止mysql服务
  • 在"/etc/mysql/mariadb.conf.d/50-server.cnf"文件中更改"datadir"变量为新路径
  • 备份/var/lib/mysql目录:"cp -R -p /var/lib/mysql /path_to_my_backup"
  • 删除/var/lib/mysql目录:"sudo rm -R /var/lib/mysql"
  • 将数据移动到新目录:"cp -R -p /path_to_my_backup /path_new_dir
  • 通过命令"sudo chown -R mysql:mysql /path_new_dir"更改访问权限
  • 在"/etc/systemd/system/mysqld.service"文件中将"ProtectHome"变量更改为"false"
  • 通过命令"sudo systemctl daemon-reload"重新加载systemd
  • 通过命令"service mysql restart"重启mysql服务
有一天我在mariadb文档中找到了这个解决方案,希望能对某些人有所帮助!

文件 /etc/systemd/system/mysqld.service 不在这里。你有什么想法在哪里找它吗? - Ron Piggott
2
对于使用 MariaDB 的用户, service 文件位于 /lib/systemd/system/mariadb@.service - Ron Piggott

6

先停止你的mysql

sudo service mysql stop

将MySQL数据复制到新位置。

sudo cp -rp /var/lib/mysql /yourdirectory/

如果您使用的是AppArmor,请编辑以下文件并按照以下步骤操作。
sudo vim /etc/apparmor.d/usr.sbin.mysqld

把 /var/lib/ 替换为 /yourdirectory/,然后将以下内容添加到文件中(如果不存在)。
    /yourdirectory/mysql/ r,
    /yourdirectory/mysql/** rwk,

使用命令保存文件:

:wq

编辑 my.cnf 文件

sudo vim /etc/mysql/my.cnf

将/var/lib/替换为/yourdirectory/,然后使用以下命令保存。
:wq

最终启动MySQL

sudo service mysql start

@查看有关raid0、优化的更多信息,请点击此处


因为它在 http://serverfault.com/a/733998/279553 中的详细信息不起作用,所以被投下反对票。 - user3338098
也许这对其他发行版不起作用,但如果你使用的是Ubuntu,那么这对我来说很好用,我会为每个新安装的Ubuntu服务器更改路径以启用RAID0。 - naddame
3
我知道有些人正在给这个帖子点踩,但我想告诉你,这篇文章让我的一天得以拯救。谢谢! - Daniel Loureiro
在启动mysql之前,必须运行“sudo systemctl restart apparmor”。 - Aigars Matulis

5

我成功地更改了 MySQLMariaDB 的数据目录,并在 Fedora 30 上解决了所有相关问题。我认为以下步骤适用于其他发行版。

注:使用类似于 UbuntuDebian-based 发行版的用户应该搜索如何禁用和编辑 AppArmor,然后按照以下步骤进行。

禁用 SELinux

首先,让我提一下,基于 RedHat 的 Linux 发行版(RHEL),例如 FedoraCentOS 等都使用强制性访问控制策略的 SELinux。因此,在以下步骤中最好将其禁用,稍后再通过一些调整启用它。

打开SELinux配置文件。

nano /etc/selinux/config

定位包含SELINUX=enforcing的行并将其值更改为SELINUX=disabled保存文件并重新启动系统。

更改MySQL的数据目录

停止MySQL服务

systemctl stop mysqld.service

为MySQl的数据目录创建一个新目录。由于某些原因超出了此解决方案的范围,强烈建议不要在/home目录下创建数据目录,但是可能有些人像我一样更喜欢它(这需要更多步骤)。

mkdir /home/eloy/applications/mysql-datadir/

新目录所有权权限设置为默认的MySQL数据目录(/var/lib/mysql):

chown --reference=/var/lib/mysql   /home/eloy/applications/mysql-datadir/
chmod --reference=/var/lib/mysql   /home/eloy/applications/mysql-datadir/

将所有文件从默认目录复制到新目录

cp -rp /var/lib/mysql/*   /home/eloy/applications/mysql-datadir/

[mysqld]部分下,编辑/etc/my.cnf文件,并添加以下行:
[mysqld]
datadir=/home/eloy/applications/mysql-datadir/

现在,您可以通过以下命令启动MySQL服务:

systemctl start mysqld.service

但是,如果数据目录创建在/home下,MySQL将无法启动,并且在执行journalctl -xe后,您会看到以下错误和警告:

Oct 05 10:22:03 eloy-fedora-laptop mysqld[8362]: 2021-10-05 10:22:03 0 [Warning] Could not increase number of max_open_files to more than 16384 (request: 32190) 
Oct 05 10:22:03 eloy-fedora-laptop mysqld[8362]: 2021-10-05 10:22:03 0 [Warning] Can't create test file /home/eloy/applications/mysql-datadir/eloy-fedora-laptop.lower-> 
Oct 05 10:22:03 eloy-fedora-laptop mysqld[8362]: [113B blob data] 
Oct 05 10:22:03 eloy-fedora-laptop mysqld[8362]: 2021-10-05 10:22:03 0 [ERROR] Aborting

解决/home问题

确保新的datadir所在路径上的所有父级目录向上具有对于所有用户(用户其他人)都有x执行)权限。我建议不使用递归脚本,因此:

chmod +x /home/eloy/applications/mysql-datadir
chmod +x /home/eloy/applications
chmod +x /home/eloy/
chmod +x /home

正如提到的那样,在/home目录下创建datadir是棘手的,因为默认情况下MySQL不允许这样做。在/etc/systemd/system/mariadb.service.d目录下创建一个文件,并添加以下行:

#open an editor to create a file
nano /etc/systemd/system/mariadb.service.d/centreon.conf 

复制以下行到新的centreon.conf文件中并保存

[Service]
ProtectHome=false 
#ProtectSystem=off

通过运行以下命令应用更改:

systemctl daemon-reload

现在您可以运行MySQL服务:

systemctl start mysqld.service

启用SELinux

再次编辑/etc/selinux/config文件,将SELINUX=disabled改为SELINUX=enforcing。保存文件并重新启动系统。

使用以下命令查询SELinux的当前状态,输出应该为enforcing

getenforce

SELinux 上下文使用 mysqld_db_t,如果未正确设置,mysqld 进程将会中止,因此您需要更新它:

semanage fcontext -a -t mysqld_db_t "/home/eloy/applications/mysql-datadir(/.*)?"

restorecon -Rv /home/eloy/applications/mysql-datadir

现在您可以运行MySQL。 干杯 ;-)


5

首先停止 mysqld 服务

mysql_install_db --user=mysql \
                 --basedir=/opt/mysql/mysql \
                 --datadir=/opt/mysql/mysql/data

接下来,在你的/etc/mysql/my.cnf中更改datadir路径。
启动mysqld。

注意事项:
#1:可能需要调整SELinux设置(如果出现问题,请尝试关闭SELinux),Apparmor(Ubuntu)也可能是问题所在。

#2:参见MySQL安装DB参考文档


5

我希望在我的电脑上保留一个数据库,同时将数据保存在外置硬盘上,并可以在两者之间进行切换。

如果您使用的是Mac,并且使用Homebrew安装了MySQL,那么这个方法适用于您。否则,您需要将MySQL datadir 替换为您电脑上相应的位置。

#cd to my data dir location
cd /usr/local/var/

#copy contents of local data directory to the new location
cp -r mysql/ /Volumes/myhd/mydatadir/

#temporarily move the old datadir
mv mysql mysql.local

#symlink to the new location
ln -s /Volumes/myhd/mydatadir mysql

当您想要切换回去时,只需执行以下操作:

mv mysql mysql.remote

mv mysql.local mysql

你现在又在使用本地数据库了。希望这能帮到你。


1
这并不完全回答所述的问题,但这正是我在寻找的内容。这是一种处理my.cnf不能很好地处理空格的边缘情况/错误的简洁方法:http://bugs.mysql.com/bug.php?id=26033。我将在那个错误报告中链接这个解决方法。 - gabe
因为它在 http://serverfault.com/a/733998/279553 中的详细信息不起作用,所以被投下反对票。 - user3338098

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接