I have no idea of what I have done here, but my InnoDB engine seems to have gone from my MySQL server. I recently upgraded it from the dotdeb repository, then installed mysql-server.
There is no mention of InnoDB in my my.cnf except some comments which explain InnoDB is enabled by default, which I don't understand. There is also no mention of InnoDB in SHOW ENGINES.
Is there something I'm missing here?
If it matters, my MySQL server version is: 5.5.24-1~dotdeb.1 (Debian).
EDIT: SHOW ENGINES:
mysql> SHOW ENGINES;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| MyISAM | DEFAULT | MyISAM storage engine | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
8 rows in set (0.00 sec)
The problem is most probably a non-matching log file size: mysql expects the innodb log files to be exactly the size that is specified in the config file. To check whether this is really the issue, do the following:
sudo /etc/init.d/mysql restart
sudo tail -n 1000 /var/log/syslog
(I'm assuming you are on Debian)
If you see some errors reported there regarding innodb and log file size (Sorry, I can't remember the exact wording of the message), then the fix is easy:
locate the logfiles (probably /var/lib/mysql/ib_logfile0 and /var/lib/mysql/ib_logfile1)
stop the mysql server
rename the log files: sudo mv /var/lib/mysql/ib_logfile0 /var/lib/mysql/ib_logfile0.bak etc.
start the mysql server
check in /var/log/syslog whether the errors are no longer happening
connect to mysql and check via SHOW ENGINES; whether InnoDB is available now...
Hope this helps!
The first thing to do is to run SHOW ENGINES at the MySQL prompt to confirm if Innodb is disabled.
If it is, check the error log for the MySQL server. It will have details on why InnoDB was disabled. There are several reasons MySQL might disable InnoDB on startup. For example, if the innodb log file size specified in my.cnf does not match the size of the existing log file(s) on disk.
I've got this problem with Debian 7 server with preinstalled mysql 5.5. There was no InnoDB engine after SHOW ENGINES
As severin mentioned before run this:
sudo /etc/init.d/mysql restart
sudo tail -n 1000 /var/log/syslog
I've got this one:
InnoDB: Error: io_setup() failed with EAGAIN after 5 attempts.
And solution on other line:
InnoDB: You can disable Linux Native AIO by setting innodb_use_native_aio = 0 in my.cnf
After adding innodb_use_native_aio = 0 to my.cnf InnodDB appeared in SHOW ENGINES
Check if you have enough space on disk and where mysql.sock is stored.
Stop MYSQL
Edit my.cnf and increase:
innodb_buffer_pool_size=100M (May vary per case)
Add:
[mysqld]
innodb_force_recovery = 1
Execute the following
mv /var/lib/mysql/ib_logfile0 /var/lib/mysql/ib_logfile0.bak
mv /var/lib/mysql/ib_logfile1 /var/lib/mysql/ib_logfile1.bak
Start MySQL and take backups just in case.
Log in to mysql and: show engines; - Check to see that InnoDB is listed and SUPPORT = YES.
If all is good up until 6, exit and edit my.cnf setting this back:
[mysqld]
innodb_force_recovery = 0
Restart MySQL
Go to your websites, check that all works, and good luck!
PS - You may want to check what caused this, perhaps working on your production server, or restarting caused your log files to get corrupted. You're in the clear for now, so have a look around and make sure all else looks good, especially free disk space and offsite backups.
Related
I'm trying to automate a mysql dump of all databases from an Azure Database for MySQL Server. Current size of databases:
mysql> SELECT table_schema "DB Name", Round(Sum(data_length + index_length) / 1024 / 1024, 1) "DB Size in MB"
FROM information_schema.tables GROUP BY table_schema;
+--------------------+---------------+
| DB Name | DB Size in MB |
+--------------------+---------------+
| db1 | 278.3 |
| db2 | 51.8 |
| information_schema | 0.2 |
| mysql | 8.9 |
| performance_schema | 0.0 |
| db3 | 43.3 |
| sys | 0.0 |
+--------------------+---------------+
7 rows in set (31.80 sec)
I have a python script, on a different VM, that calls mysqldump to dump all of these into a file. However, I'm running into an issue with db1. It is being dumped to a file but it is very slow, less than ~4MB in 30min. However db2 and db3 are dumped almost immediately, in seconds.
I have tried all of the following options and combinations to see if the write speed changes, but it doesn't:
--compress
--lock-tables (true / false)
--skip-lock-tables
--max-allowed-packet (512M)
--quick
--single-transaction
--opt
I'm currently not even using the script, just running the commands in a shell, with the same result.
mysqldump -h <host> -P <port> -u'<user>' -p'<password>' db1 > db1.sql
db1 has ~500 tables.
I understand that it is bigger than db2 and db3 but it's not by that much, and I'm wondering if anyone knows what could be the issue here?
EDIT
After these helpful answers and google research showed that the database is most likely fine, I run test by duplicating the db1 database on the server into a test database and then deleting tables one by one to decrease the size. And at around 50MB the writes became instant like the other databases. This leads me to believe that there is some throttling going on in Azure because the database is just fine and we will take it up with their support team. I have also found a lot of posts on google complaining about Azure database speeds in general.
In the meantime, I changed the script to ignore large databases. And we will try to move the databases to a SQL Server provided by Azure or a simple VM with a mysql server on it to see where we can get a better performance.
It's possible it's slow on the MySQL Server end, but it seems unlikely. You can open a second shell window, connect to MySQL and use SHOW PROCESSLIST or SHOW ENGINE INNODB STATUS to check for stuck queries or locks.
It's also possible it's having trouble writing the data to db1.sql, if you have very slow storage. But 4MB is 30min. is ridiculous. Make sure you're saving to storage local to the instance you're running mysqldump on. Don't save to remote storage. Also be careful if the storage volume to which you're writing the dump has other heavy I/O traffic saturating it, this could slow down writes.
Another way you can test for slow data writes is to try mysqldump ... > /dev/null and if that is fast, then it's a pretty good clue that the slowness is the fault of the disk writes.
Finally, there's a possibility that the network is causing the slowness. If saving the dump file to /dev/null is still slow, I'd suspect the network.
An answer in
https://serverfault.com/questions/233963/mysql-checking-permission-takes-a-long-time suggests that slowness in "checking permissions" might be caused by having too much data in the MySQL grant tables (e.g. mysql.user). If you have thousands of user credentials, this could be the cause. You can try eliminating these entries (and run FLUSH HOSTS afterwards).
Create a backup from your database first. After that, try this:
mysqlcheck
More info about this: mysqlcheck
Looking at the mariadb logs, I am seeing all the passwords logged in as clear text like IDENTIFIED BY . Is there any option or way yo suppress this. This is a huge security risk.
Any help is appreciated.
MariaDB [(none)]> SHOW VARIABLES LIKE "%version%";
+-------------------------+-----------------------------------+
| Variable_name | Value |
+-------------------------+-----------------------------------+
| innodb_version | 5.5.41-MariaDB-37.0 |
| protocol_version | 10 |
| slave_type_conversions | |
| version | 5.5.42-MariaDB-wsrep |
| version_comment | MariaDB Server, wsrep_25.11.r4026 |
| version_compile_machine | x86_64 |
| version_compile_os | Linux |
+-------------------------+-----------------------------------+
If you use audit plug-in v1.2 or newer, then mariadb masks the passwords in certain queries. Specifically:
Since version 1.2.0, passwords have been replaced by asterisks in the logs for certain queries, including:
GRANT, CREATE USER, CREATE MASTER, CREATE SERVER, ALTER SERVER
Passwords given with the PASSWORD() and OLD_PASSWORD() functions in
DML statements will still be logged as plain text in queries, as will
key strings used with encrypt functions such as ENCODE() and
AES_ENCRYPT().
Furthermore, you can protect the log files via traditional means by restricting access rights, using file system level encryption. Really, only DBAs should have access to server logs and they can pretty much do anything in the db anyway.
The clear text password is not only logged in the MariaDB logs but it might be also logged in the .mysql_history file of the user that connected to MariaDB and performed some
CREATE/GRANT/etc.. IDENTIFIED BY 'some_cleartext_password'
You can find .mysql_history in /home/username or in /root if you connected as root.
Best way to avoid such things to happen is to replace the syntax
CREATE/GRANT/etc.. IDENTIFIED BY 'some_cleartext_password'
with
CREATE/GRANT/etc.. IDENTIFIED BY PASSWORD 'hashed_password'
You can calculate the hashed password either in your application that is calling MariaDB or by using the PASSWORD() function of MariaDB. For example:
SELECT PASSWORD('some_cleartext_password')
Do the above select on another MariaDB/MySQL server if you don't want the above query to be logged, in which case you will end-up with the same problem. :-)
I run the following query from my shell :
mysql -h my-host.net -u myuser -p -e "SELECT component_id, parent_component_id FROM myschema.components comp INNER JOIN my_second_schema.component_parents related_comp ON comp.id = related_comp.component_id ORDER BY component_id;" > /tmp/IT_component_parents.txt
The query runs for a LONG time and then gets KILLED.
However if I add LIMIT 1000, then the query runs till the end and output is written in file.
I further investigated and found (using COUNT(*)) that the total number of records that would be returned are 239553163.
Some information about my server is here:
MySQL 5.5.27
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| connect_timeout | 10 |
| delayed_insert_timeout | 300 |
| innodb_lock_wait_timeout | 50 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| wait_timeout | 28800 |
+----------------------------+----------+
Here's STATE of the query as I monitored :
copying to tmp table on disk
sorting results
sending data
writing to net
sending data
writing to net
sending data
writing to net
sending data ...
KILLED
Any guesses what's wrong here ?
The mysql client probably runs out of memory.
Use the --quick option to not buffer results in memory.
What is wrong is that you are returning 239 553 163 rows of data! Don't be surprised it it takes a lot of time to process. Actually, the longest part might very well be sending the result set back to your client.
Reuduce the result set (do you really need all these rows?). Or try to output the data in smaller batches:
mysql -h my-host.net -u myuser -p -e "SELECT ... LIMIT 10000, 0" >> dump.txt
mysql -h my-host.net -u myuser -p -e "SELECT ... LIMIT 10000, 10000" >> dump.txt
Assuming you mean 8 hours when you say a long time, the value 28800 for your wait_timeout causes the connection to drop with no further activity in 28,800 seconds, i.e. 8 hours. If you can't optimize the statement to run in less than 8 hours, you should increase this value.
See this page for further information on the wait_timeout variable.
The interactive_timeout variable is used for interactive client connections, so if you run long queries from an interactive session, that's the one you need look at.
You may want to utilize OUTFILE mechanizm if you are going to dump large amounts of data. That or mysql_dump will be much more efficient (and OUTFILE got the benefit of not locking-down the table).
You said in a comment that your MySQL instance is on RDS. This means you can't be running the query from the same host, since you can't log into an RDS host. I guess you might be doing this query over the WAN from your local network.
You're most likely having trouble because of a slow network. Your process state frequently showing "writing to net" makes me think this is your bottleneck.
Your bottleneck might also be the sorting. Your sort is writing to a temp table, and that can take a long time for a result set that large. Can you skip the ORDER BY?
Even so, I wouldn't expect the query to be killed even if it runs for 3100 seconds or more. I wonder if your DBA has some periodic job killing long-running queries, like pt-kill. Ask your DBA.
To reduce network transfer time, you could try using the compression protocol. You can use the --compress or -C flags to the mysql client for this (see https://dev.mysql.com/doc/refman/5.7/en/mysql-command-options.html#option_mysql_compress)
On a slow network, compression can help. For example, read about some comparisons here: https://www.percona.com/blog/2007/12/20/large-result-sets-vs-compression-protocol/
Another alternative is to run the query from an EC2 spot instance running in the same AZ as your RDS instance. The network between those two instances will be a lot faster, so it won't delay your data transfer. Save the query output to a file on the EC2 spot instance.
Once the query result is saved on your EC2 instance, you can download it to your local machine, using scp or something, which should be more tolerant of slow networks.
I have one MySQL Master and several slave machines.
master-slave replication is set and works perfectly.
At this point, I want to add a new slave machine:
My question relates to the "CHANGE MASTER TO" command:
Assuming that all the files are available on the master, I will start from mysql-bin.000001, but from which position ? MASTER_LOG_POS=0 ? MASTER_LOG_POS=1 ? Something else ?
CHANGE MASTER TO
MASTER_HOST='...',
MASTER_USER='...',
MASTER_PASSWORD='...',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=WHAT_SHOULD_WRITE_HERE;
10x,
You should execute show master status; for example,
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000011 | 13966886 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
before taking dump on master and note the log position. Restore dump on slave and run change master to with same log position 13966886 which you have got before mysqldump.
If you have all the bin logs from the start of time you can use use master_log_file .000001 and pos=0. Most people don't have the binary logs from the master start anymore, so the position to use is the one that was when the dump was taken. The dump that you copied to your slave server. Or the position when you closed your master and copied data directories.
You already have a slave server so this makes it easier for you. You can stop the slave thread on the slave server, check the logfile name and position from the slave, copy the datafiles from the slave to the new server and start both.
The docs say to run SHOW MASTER STATUS: (http://dev.mysql.com/doc/refman/5.6/en/replication-howto-masterstatus.html)
SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 73 | test | manual,mysql |
+------------------+----------+--------------+------------------+
Your position is in the second column.
I use PHP to access MySQL in XAMPP. My question is where I can find the MySQL log file if there is a DB error.
Also, can I change the default location/name of that log file?
Thank you
///// Based on the coments //////
mysql> show variables like '%log_file%';
+---------------------------+------------------------------------+
| Variable_name | Value |
+---------------------------+------------------------------------+
| general_log_file | C:/xampp/mysql/data/mysql.log |
| innodb_log_file_size | 5242880 |
| innodb_log_files_in_group | 2 |
| slow_query_log_file | C:/xampp/mysql/data/mysql-slow.log |
+---------------------------+------------------------------------+
4 rows in set (0.00 sec)
If you do
SHOW VARIABLES LIKE '%log_file%';
it will show exactly where they're being written.
The accepted answer is a bit old, for MySQL 5.1+
you may use the queries:
SET GLOBAL general_log = 'ON';
SET GLOBAL general_log_file = 'my_log.log';
First will enable loging (which may be off by default)
and the second select updates the preferred file (by default under C:/xampp/mysql/data/).
NOTE: On windows 8 you may have to run your SQL IDE as ADMINISTRATOR for this commands to get saved.
NOTE2: you can also set this in the config, go to path_to_xampp/mysql/ and edit my.ini
(copy from my-default.ini if it does not exists) and add the settings there:
[mysqld]
general_log = 'ON';
general_log_file = 'my_log.log';
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
It's a *.err file.
You will find it here : C:\xampp\mysql\data
To trace you error correctly, open it with Notepad++ for example and Start Mysql. You Should see the error at the end of the file.
You can also try looking at localhost/phpmyadmin/ and click on the Variables tab.
On mac, it's likely to be at:
/Applications/XAMPP/xamppfiles/var/mysql
If there are a lot of error files there, do ls -la to see which one is most recent and most likely.