You can get the following error in your Apache ‘s error logs if you’re using PHP as a means to retrieve data from your database.
PHP Warning: Table “tbl_name” is read only
query: [SQL query]
Try the following to fix it. First, see if your user with which you’re connecting has enough privileges.
mysql> SHOW GRANTS FOR CURRENT_USER;
+-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-—-+
| Grants for dbuser@% |
+-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-—-+
| GRANT USAGE ON *.* TO ‘dbuser’@’%’ IDENTIFIED BY PASSWORD ‘randomhex’ |
| GRANT ALL PRIVILEGES ON `dbname`.* TO ‘dbuser’@’%’ |
+-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-–-—-+
2 rows in set (0.00 sec)
You should at least have the necessary privileges on your specific table. If that’s the case, try to repair the table (it may have crashed).
mysql> REPAIR TABLE tbl_name;
+-–-–-–-–-–-—+-–-—-+-–-–-—+-–-–-–-–-–-–-–-–-–-–-–-–-—+
| Table | Op | Msg_type | Msg_text |
+-–-–-–-–-–-—+-–-—-+-–-–-—+-–-–-–-–-–-–-–-–-–-–-–-–-—+
| dbuser.tbl_name| repair | error | Table ‘dbname.tbl_name’ is read only |
+-–-–-–-–-–-—+-–-—-+-–-–-—+-–-–-–-–-–-–-–-–-–-–-–-–-—+
1 row in set, 1 warning (0.00 sec)
If you’re still getting “read only” messages, check the file permissions in /var/lib/mysql/dbname/tbl_name (assuming your database is in /var/lib/mysql).
# ls -alh /var/lib/mysql/dbname/
total 209M
drwx-–-– 2 mysql mysql 16K Jul 20 10:42 .
drwxr-xr-x 187 mysql mysql 4.0K Jul 11 12:22 ..
-rw-r–r– 1 root root 1.0K Jun 28 06:14 tbl_name.MYI
-rw-r–r– 1 root root 8.4K Jun 28 06:14 tbl_name.frm
The files should be owned by “mysql” with the group “mysql”, if your MySQL is running as the mysql user. Stop the MySQL daemon, change the ownership and restart your MySQL.
# /etc/init.d/mysqld stop
Stopping MySQL: [ OK ]
# chown mysql.mysql /var/lib/mysql/dbname/*
# /etc/init.d/mysqld start
Starting MySQL: [ OK ]
MariaDB upgrade fails on Debian 8.x with Directadmin, and here is a possible solution. Found the issue with upgrading from 10.0.35 to 10.0.36.
Can’t connect to local MySQL server through socket
SQL server is not available with the following error:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/usr/local/mysql/data/mysql.sock' (2)
And if you see the similar lines in the server error log:
180909 17:04:07 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
180909 17:04:07 [ERROR] Can't open and lock privilege tables: Table './mysql/servers.MYI' is read only
180909 17:04:07 [Note] Server socket created on IP: '127.0.0.1'.
180909 17:04:07 [ERROR] Fatal error: Can't open and lock privilege tables: Table './mysql/host.MYI' is read only
180909 17:04:07 mysqld_safe mysqld from pid file /usr/local/mysql/data/mysqld.pid ended
Have no issue with MariaDB 10.0.35 (if to downgrade back to the version). The SQL server starts, and no issue is found. Hence it can not be an issue with files/folders permissions.
And none of master/slave replication is enabled.
Is that because of Selinux?
The server has selinux disabled
Probably AppArmor?
AppArmor does not seem to be enabled.
root@hosting:/etc/apparmor.d# service apparmor status ● apparmor.service Loaded: not-found (Reason: No such file or directory) Active: inactive (dead) root@hosting:/etc/apparmor.d#
If to do a fresh installation?
A fresh installed MariaDB 5.5.x fails the same way even after:
/usr/local/mysql/scripts/mysql_install_db --basedir=/usr/local/mysql/
it installs all the tables and fails to start afterwards.
Nothing helps?
So we can’t start any other MariaDB version, but 10.0.35.
Reasons?
The reason for this is that newer MariaDB versions need read access all the way down the path (not too sure why, but they do), eg:
openat(-1, "/home", O_RDONLY|O_NOFOLLOW|O_PATH) = -1 EACCES (Permission denied)
openat(-1, "/home", O_RDONLY|O_NOFOLLOW|O_PATH) = -1 EACCES (Permission denied)
write(2, "180910 16:04:47 [ERROR] Fatal error: Can't open and lock privilege tables: Table './mysql/host.MYI' is read onlyn", 113180910 16:04:47 [ERROR] Fatal error: Can't open and lock privilege tables: Table './mysql/host.MYI' is read only
and we cannot change /home to 755 for security reasons.
/home should be 711 so it’s contents cannot be read by Users.
Let’s move datadir then…
Change/add datadir= in /etc/my.cnf from /home/mysql/ and move databases to /var/lib/mysql/:
datadir = /var/lib/mysql/
and MariaDB 10.0.36 should start fine on your Debian 8 server.
Complete upgrade with:
/usr/local/mysql/bin/mysql_upgrade
And what about Directadmin?
New installs of Directadmin (since version 1.54) will address these changes in MariaDB and install MySQL data into /var/lib/mysql.
- Debian: MySQL/MariaDB will install data to /var/lib/mysql from /home/mysql
That’s it.
If you don’t know how to do it, contact us for a paid service.
I am facing problem restoring a MySQL database. My primary database was MySQL 5.1 and now I am trying to copy it to MySQL 5.5. The database was backed up by using Xtrabackup.
I am using Ubuntu 12.04.3 LTS on this server, MySQL version is: 5.5.32-0ubuntu0.12.04.1-log
.
I have followed all the steps to restore using Xtrabackup, this created database files, which I have copied to a tmp directory.
I have modified my.cnf
to point to this tmp directory. I have changed the tmp directory permissions and changed the ownership of the files to mysql
user.
drwxr-xr-x 12 mysql mysql 4096 Sep 10 10:04 base
Now when I start the MySQL server I get this error:
[ERROR] Fatal error: Can’t open and lock privilege tables: Table ‘host’ is read only
I have given a try as follows:
-
Even tried installing MySQL 5.1 to see if that was the issue.
-
tried
chcon mysql_db_t
to change the context but it gives me:can’t apply partial context to unlabelled file
-
I have used
--skip-grant
to get into database, but using this I can only access InnoDB tables only, MyISAM tables throw read-only error. -
After
--skip-grant
, I have usedupgrade_mysql
. This throws me errors stating that many tables are read-only. -
I have removed AppArmor too. And restarted too.
-
I have restored a different database (5.1 to 5.5) previously on Ubuntu 12.04.2 LTS without any issues.
Can some please point me in right direction? I am not sure whats wrong with permissions.
asked Sep 10, 2013 at 7:46
2
custom mysql datadir? removed apparmor and still having mysql process failing to start issues? try this. may help some of you depending on your config. worked for me:
when using a custom mysql (5.5) data dir as described above-
ie., if the abs. path to datadir (my.cnf) is
/opt/some/other/mysql
even with apparmor removed/purged, you must make certain that permissions on ALL of the folders in the mysql datadir path are perm’d correctly. this is a mysql convention- not related to apparmor.
look at /var/lib/mysql- the default datadir (my.cnf) on most installations: perms are 755 for /var and /var/lib.
in my custom datadir example above, when I set any/all of the dirs called ‘opt’ or ‘some’ or ‘other’ without an execute permission for allusers (ie., 750), mysql will not start. once i add an execute perm to allusers (ie. 755, 771, etc.), BINGO. mysql starts.
answered Nov 14, 2013 at 22:47
The issue is with AppArmor. I am not sure why MySql is unable to access files even after uninstalling AppArmor.
Reinstalled AppArmor and moved the MySql profile under disabled profiles of AppArmor, even then it did not work.
I copied the database files under /var/lib/mysql/ and MySql stopped throwing errors
answered Sep 11, 2013 at 3:44
PraveenPraveen
211 gold badge1 silver badge2 bronze badges
I faced the same issue… In Ubuntu systems you need to change the permissions for the new datadir.
Goto
/etc/apparmor.d/usr.sbin.mysqld
change the datadir path /var/lib/mysql to new-datadir OR add new lines
chown -R mysql:mysql “new datadir path”
Then it runs smoothly.
answered Sep 12, 2013 at 16:43
VinayVinay
1358 bronze badges
I’ve tried all of solutions I can found over the Internet. But this one is what worked for me.
So existing datadir is at /var/lib/mysql
.
I had it copied to /mnt/var/lib/mysql
via cp -a <src> <dest>
( /mnt
is Amazon EBS mountpoint )
Naturally I would have thought the -a
switch should have taken care of everything. But upon checking the execute bit for o(thers)
, for /var
and /mnt
, they are different, the latter’s is disabled. So I enabled it and yes, it is now functioning.
The thing is, mysql
is not the first occupant of /mnt/var/lib
. I earlier moved PostgreSQL datadir there, and it did not complain about having no execute permissions for o.
answered Dec 5, 2013 at 2:04
If you move your datadir, you not only need to give the new datadir permissions, but you need to insure all parent directories have permission.
I moved my datadir to a hard drive, mounted in Ubuntu as:
/media/*user*/Data/
and my datadir was Databases.
I had to set permissions to 771 to each of the media, user and Data directories:
sudo chmod 771 *DIR*
If this does not work, another way you can get mysql to work is to change user in /etc/mysql/my.cnf to root; though there are no doubt some issues with doing that from a security perspective.
answered Oct 9, 2014 at 12:36