You are here
Agrégateur de flux
Beware of large MySQL max_sort_length parameter
Today we had a very interesting phenomena at a customer. He complained that MySQL always get some errors of the following type:
[ERROR] mysqld: Sort aborted: Error writing file '/tmp/MYGbBrpA' (Errcode: 28 - No space left on device)After a first investigation we found that df -h /tmp shows from time to time a full disk but we could not see any file with ls -la /tmp/MY*.
After some more investigation we found even the query from the Slow Query Log which was producing the same problem. It looked similar to this query:
SELECT * FROM test ORDER BY field5, field4, field3, field2, field1;Now we were capable to simulate the problem at will with the following table:
CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `data` varchar(64) DEFAULT NULL, `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `field1` varchar(16) DEFAULT NULL, `field2` varchar(16) DEFAULT NULL, `field3` varchar(255) DEFAULT NULL, `field4` varchar(255) DEFAULT NULL, `field5` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=8912746 DEFAULT CHARSET=utf8 ;An we have seen the query in SHOW PROCESSLIST:
| Query | 26 | Creating sort index | select * from test order by field5, field4, field3, field2, field1 |But we were still not capable to see who or better how the hell mysqld is filling our disk!
I remembered further that I have seen some strange settings in the my.cnf before when we did the review of the database configuration. But I ignored them somehow.
[mysqld] max_sort_length = 8M sort_buffer_size = 20MNow I remembered again these settings. We changed max_sort_length back to default 1k and suddenly our space problems disappeared!
We played a bit around with different values of max_sort_length and got the following execution times for our query:
max_sort_lengthexecution time [s]comment 64 8.8 s128 8.2 s256 9.3 s512 11.8 s 1k 14.9 s 2k 20.0 s 8k129.0 s 8M 75.0 sdisk full (50 G)Conclusion
We set the values of max_sort_length back to the defaults. Our problems disappeared and we got working and much faster SELECT queries.
Do not needlessly change default values of MySQL without proving the impact. It can become worse than before!!!
The default value of max_sort_length is a good compromise between performance and an appropriate sort length.
AddendumWhat I really did not like on this solution was, that I did not understand the way the problem occurred. So I did some more investigation in this. We were discussing forth and back if this could be because of XFS, because of sparse files or some kind of memory mapped files (see also man mmap).
At the end I had the idea to look at the lsof command during my running query:
mysql> SELECT * FROM test ORDER BY field5, field4, field3, field2, field1; ERROR 3 (HY000): Error writing file '/tmp/MYBuWcXP' (Errcode: 28 - No space left on device) shell> lsof -p 14733 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 14733 mysql 32u REG 8,18 9705619456 30147474 /tmp/MYck8vf4 (deleted) mysqld 14733 mysql 49u REG 8,18 749797376 30147596 /tmp/MYBuWcXP (deleted)So it looks like that there were some deleted files which were growing!
Further information from the IRC channel led me to the libc temporary files (see also man 3 tmpfile).
And some hints from MadMerlin|work pointed me to:
shell> ls /proc//fdWhere you can also see those temporary files.
Thanks to MadMerlin|work for the hints!
Taxonomy upgrade extras: sortfileorder byBeware of large MySQL max_sort_length parameter
Today we had a very interesting phenomena at a customer. He complained that MySQL always get some errors of the following type:
[ERROR] mysqld: Sort aborted: Error writing file '/tmp/MYGbBrpA' (Errcode: 28 - No space left on device)After a first investigation we found that df -h /tmp shows from time to time a full disk but we could not see any file with ls -la /tmp/MY*.
After some more investigation we found even the query from the Slow Query Log which was producing the same problem. It looked similar to this query:
SELECT * FROM test ORDER BY field5, field4, field3, field2, field1;Now we were capable to simulate the problem at will with the following table:
CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `data` varchar(64) DEFAULT NULL, `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `field1` varchar(16) DEFAULT NULL, `field2` varchar(16) DEFAULT NULL, `field3` varchar(255) DEFAULT NULL, `field4` varchar(255) DEFAULT NULL, `field5` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=8912746 DEFAULT CHARSET=utf8 ;An we have seen the query in SHOW PROCESSLIST:
| Query | 26 | Creating sort index | select * from test order by field5, field4, field3, field2, field1 |But we were still not capable to see who or better how the hell mysqld is filling our disk!
I remembered further that I have seen some strange settings in the my.cnf before when we did the review of the database configuration. But I ignored them somehow.
[mysqld] max_sort_length = 8M sort_buffer_size = 20MNow I remembered again these settings. We changed max_sort_length back to default 1k and suddenly our space problems disappeared!
We played a bit around with different values of max_sort_length and got the following execution times for our query:
max_sort_lengthexecution time [s]comment 64 8.8 s128 8.2 s256 9.3 s512 11.8 s 1k 14.9 s 2k 20.0 s 8k129.0 s 8M 75.0 sdisk full (50 G)Conclusion
We set the values of max_sort_length back to the defaults. Our problems disappeared and we got working and much faster SELECT queries.
Do not needlessly change default values of MySQL without proving the impact. It can become worse than before!!!
The default value of max_sort_length is a good compromise between performance and an appropriate sort length.
AddendumWhat I really did not like on this solution was, that I did not understand the way the problem occurred. So I did some more investigation in this. We were discussing forth and back if this could be because of XFS, because of sparse files or some kind of memory mapped files (see also man mmap).
At the end I had the idea to look at the lsof command during my running query:
mysql> SELECT * FROM test ORDER BY field5, field4, field3, field2, field1; ERROR 3 (HY000): Error writing file '/tmp/MYBuWcXP' (Errcode: 28 - No space left on device) shell> lsof -p 14733 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 14733 mysql 32u REG 8,18 9705619456 30147474 /tmp/MYck8vf4 (deleted) mysqld 14733 mysql 49u REG 8,18 749797376 30147596 /tmp/MYBuWcXP (deleted)So it looks like that there were some deleted files which were growing!
Further information from the IRC channel led me to the libc temporary files (see also man 3 tmpfile).
And some hints from MadMerlin|work pointed me to:
shell> ls /proc//fdWhere you can also see those temporary files.
Thanks to MadMerlin|work for the hints!
Taxonomy upgrade extras: sortfileorder byFromDual Schulung MySQL und SQL für Einsteiger
FromDual bietet zusammen mit der GFU Cyrus GmbH in Köln vom 17. - 21. Oktober 2016 eine MySQL und SQL Schulung für Einsteiger an.
Anmelden können Sie sich unter Schulungstermine für MySQL und MariaDB.
Taxonomy upgrade extras: schulungmysqlmariadbtrainingmysql-trainingmysql-schulungsqleinsteigerFromDual Schulung MySQL und SQL für Einsteiger
FromDual bietet zusammen mit der GFU Cyrus GmbH in Köln vom 17. - 21. Oktober 2016 eine MySQL und SQL Schulung für Einsteiger an.
Anmelden können Sie sich unter Schulungstermine für MySQL und MariaDB.
Taxonomy upgrade extras: schulungmysqlmariadbtrainingmysql-trainingmysql-schulungsqleinsteigerFromDual Schulung MySQL und SQL für Einsteiger
FromDual bietet zusammen mit der GFU Cyrus GmbH in Köln vom 17. - 21. Oktober 2016 eine MySQL und SQL Schulung für Einsteiger an.
Anmelden können Sie sich unter Schulungstermine für MySQL und MariaDB.
Taxonomy upgrade extras: schulungmysqlmariadbtrainingmysql-trainingmysql-schulungsqleinsteigerFromDual Performance Monitor for MySQL and MariaDB 0.10.6 has been released
FromDual has the pleasure to announce the release of the new version 0.10.6 of its popular Database Performance Monitor for MySQL, MariaDB, Galera Cluster and Percona Server fpmmm.
You can download fpmmm from here.
In the inconceivable case that you find a bug in fpmmm please report it to our Bug-tracker.
Any feedback, statements and testimonials are welcome as well! Please send them to feedback@fromdual.com.
This release contains various bug fixes and improvements. The previous release had some major bugs so we recommend to upgrade...
Changes in fpmmm v0.10.6 fpmmm agent- Do not connect to server bug fixed.
- Special case when lock file was removed when it was read is fixed.
- Added ORDER BY to all GROUP BY to be compliant for the future.
- Zabbix 3.0 templates added.
- MaaS: Function curl_file_create implemented for php < 5.5
- MaaS: Debug message fixed.
- Maas: Curl upload fixed.
- MaaS: InnoDB: Deadlock and Foreign Key errors are only escaped with xxx when used in MaaS. Otherwise they are sent normally. Foreign Key errors with MaaS is now also escaped with xxx.
- Wrong substitution in process vm calculation fixed.
- Template: Galera items changed from normal to delta.
- Template: Fixed InnoDB template to work with Zabbix v3.0.
- Template: InnoDB locking graph improved.
For subscriptions of commercial use of fpmmm please get in contact with us.
Taxonomy upgrade extras: mysqlperformancemonitormonitoringfpmmmmaasperformance monitormpmreleaseMySQL Environment MyEnv 1.3.1 has been released
FromDual has the pleasure to announce the release of the new version 1.3.1 of its popular MySQL, Galera Cluster, MariaDB and Percona Server multi-instance environment MyEnv.
The new MyEnv can be downloaded here.
In the inconceivable case that you find a bug in the MyEnv please report it to our bug tracker.
Any feedback, statements and testimonials are welcome as well! Please send them to feedback@fromdual.com.
Upgrade from 1.1.x or higher to 1.3.1 # cd ${HOME}/product # tar xf /download/myenv-1.3.1.tar.gz # rm -f myenv # ln -s myenv-1.3.1 myenvIf you are using plug-ins for showMyEnvStatus create all the links in the new directory structure:
cd ${HOME}/product/myenv ln -s ../../utl/oem_agent.php plg/showMyEnvStatus/Changes in MyEnv 1.3.1 MyEnv
- Bash function bootstrap added.
- Galera options --bootstrap --new-cluster and start method bootstrap was implemented. Typo fixed.
- New 5.7 variables added and 5.6 variables to avoid nasty warnings in the error log added to the my.cnf template. Further new file system structure was prepared.
- MySQL 5.7 variables for error log behaviour added.
- Comment for log_bin added to my.cnf template.
- ulimit problem fixed rudely in MyEnv init script.
- wsrep_provider for CentOS added in my.cnf template.
- Cgroup template improved.
- Cgroup how-to improved and configuration example added.
- default as instance name set to blacklist.
- Typo fixed in help of installMyEnv.
- Test table prepared for explicit_defaults_for_timestamp configuration.
- insert_test.sh now has optional parameters for user, host etc.
For subscriptions of commercial use of MyEnv please get in contact with us.
Taxonomy upgrade extras: myenvoperationMySQL Operationsmulti instanceconsolidationtestingupgradereleasecloudcgroupscontainermysqld_multiMultiple MySQL Instances on a Single Machine
Typically, on a single machine (be it a physical or a virtual one) only a single MySQL instance (process) is running. This is perfectly ok for all those situations where a single instance is sufficient, like for storing small amounts of data (RedHat using MySQL for postfix, KDE using it for akonadi, ...), as well as those where a dedicated machine per MySQL instance is appropriate (high CPU load, memory fully loaded, availability requirements).
But there are also those users who want to (or would like to) have multiple instances which would still fit into a single machine. Even among them, a single instance per machine is typical. For this, there are good reasons:
- MySQL comes with defaults for files (config file, error log, ...) and directories (data directory, binlogs, ...) which would cause conflicts between multiple instances (unless they are changed).
- The scripts coming with MySQL, especially the automated start/stop with machine reboot/shutdown, are written for a single instance only.
- Last but not least: The instructions. those in the manual as well as the many "How to setup ..." in the Web, cover a single instance only.
But that overhead (both in software and in labour) isn't necessary: There is a way out, supporting easy handling of multiple MySQL instances on a single machine directly, without containers or VMs. This is our "MyEnv" package, available for download here, licensed under the GPL.
What Does MyEnv Do?MyEnv cares about two aspects which in combination provide easy use of multiple instances:
- It helps to configure multiple MySQL instances without overlap, so they won't collide with each other.
- It maintains separate environments, each to manage and access one specific instance.
Each environment contains the path to the binaries (so the instances can use different versions), the config file, the socket and port number, data directory, error log etc. The environment is specified by a name (choose a meaningful one!), and it is switched by using its name as a shell command. (MyEnv creates an alias for that.)
Administrative commands like "start" and "stop" will manage the instance of the current environment. MySQL client programs like "mysql" or "mysqldump" will access that instance.
MyEnv supports the autostart of instances at machine boot, configurable per instance - something which is impossible using only the tools of a MySQL distribution.
Of course, an instance started via MyEnv (either manually or via autostart) can be accessed by any other client program on the machine, or from any other machine in the network - all that is needed is the specification of the proper socket or network port.
Handling Multiple Binaries
In the previous section, I wrote the instances can use different versions.
This is done by installing those different versions into different locations, controlled by MyEnv, and the directory with the binaries will become a component of the user's PATH variable, switched when the environment is switched.
Obviously, this works only if the destination path of the installation can be controlled, which implies the tar.gz format - RPM or DEB packages have fixed destinations, so different versions would overwrite each other on installation.
But that is no severe limitation, as all MySQL versions are available in tar.gz format, and these are sufficiently generic to run on any reasonably current Linux distribution.
(Yes, that is something I forgot to mention:
MyEnv is developed and tested on Linux only.
You are welcome to try it on any other Unix platform, and we will gladly listen to your experiences and accept your contributions, but we do not actively pursue non-Linux platforms.)
This support for multiple versions makes MyEnv the perfect tool for application development: Using a single machine, you can let your application access the MySQL servers of different versions and can verify it works the way you want it to.
Similar, you can install binaries of MySQL (Oracle), Percona Server, or MariaDB, and verify your application is portable across them.
And the adventurous among us can use different binaries, from the same or different vendor(s), to test whether replication works across versions and/or vendors, all without the effort of installing a separate VM or container setup.
MyEnv and Galera Cluster Till now, I mentioned MySQL (and its variants), and many readers may associate that term with a traditional single instance. So I better state explicitly: Of course, such an instance can take part in replication, in any role: master, slave, or intermediate in multi-level replication.But besides single instances and replication, there exists a different MySQL setup: Nodes combined to form a Galera Cluster. And again, let me state explicitly: Again of course, an instance controlled by MyEnv can be a node participating in a Galera Cluster.
Those readers who have experiance with Galera Cluster (or who have just read the documentation or blogs about it) know that to start the first node of a cluster a special command is needed, called "bootstrap" - a simple "start" will not do. So this command was also added to MyEnv, it can manage a Galera Cluster completely by its builtin commands.
RPM and DEB packages Above, I wrote that to install different versions you cannot use RPM or DEB packages. I did not write that MyEnv cannot use RPM or DEB - in fact it can, the absolute path names in these formats just limit this to a single version.So you can install the RPM or DEB of your choice, disable its autostart, and then call MyEnv to create multiple instances. You will give them different names, specify different sockets and ports and use different data directories, but for all of them you will specify the same path "/usr". As a result, MyEnv will simply manage multiple instances of the same version.
You can configure them differently to test the consequences, or you can set them up to replicate among them - master and slave can run on the same machine. Of course, this will not give you the "high availability" or the "scale-out" benefits which are the typical reasons to use replication, but I trust this wasn't your purpose for this test.
Using binaries that include Galera, and configuring them properly, you can even run all nodes of a Galera Cluster as separate instances on a single machine. That may be considered to stretch the concept, because a single machine is a very different setup than separate machines, but it gives an idea of the possibilities opened by MyEnv.
Typical Use of MyEnvAdmitted: The claim to know what MyEnv is used for by others would be arrogant, and I do not uphold it. Nonetheless, we do know some use cases of people who downloaded MyEnv, and they are close to our internal use of the tool.
MyEnv allows to have multiple MySQL instances on the same machine, to manage them separately, and to access them using MySQL client programs or other applications. So it is the perfect setup for all those who need to access different versions: developers and software testers.
When we encounter some unexpected behaviour, we often want to know whether it is specific to some version or series, or is widespread. To check that, MyEnv is the perfect infrastructure: You write a test case to provoke the effect and run it on several versions, then you note the result and can tell whether it exists "since ages" or is new, whether it still occurs in current versions or will change with an upgrade - exactly the information you need to decide about an upgrade or write a bug report.
Database administrators and application developers use it to avoid nasty surprises with new versions, so their production instances will not suffer from unexpected functional changes. Setting up a test environment, especially for multiple versions, becomes cheap, much less ressources are needed. You don't need to copy your test code onto different machines, and you are sure you are running identical tests, so that you won't compare apples and oranges.
InvitationIf all that made you curious, I invite you to look into the instructions, to download MyEnv and to try it. And of course, your feedback and reports are very welcome.
Take care!
Appendix: Where to Meet UsAll FromDual colleagues will deliver talks at the FrOSCon in St. Augustin near Cologne, Germany, on August 20 and 21, so that is a good opportunity for personal contact. As several talks will be delivered in English, the conference also meets the needs of attendants who cannot follow a German talk - check the programme. Froscon is a famous event, very interesting talks are promised, and I look forward to enjoy the community atmosphere there.
I will deliver a talk at the "Open Source Backup Conference" in Cologne, Germany, on September 26 and 27; this conference is held in English.
I do not have feedback yet about Percona Live in Amsterdam, I may attend that also.
And finally, FromDual will again have a booth and deliver talks at the DOAG conference on November 15 - 18 in Nuremberg, Germany. This is "the" event for Oracle users (at least in Germany, maybe in all Europe), and it has a separate track dealing with MySQL only.
We will be delighted to meet you face to face!
Taxonomy upgrade extras: MyEnvMultiple MySQL Instances on a Single Machine
Typically, on a single machine (be it a physical or a virtual one) only a single MySQL instance (process) is running. This is perfectly ok for all those situations where a single instance is sufficient, like for storing small amounts of data (RedHat using MySQL for postfix, KDE using it for akonadi, ...), as well as those where a dedicated machine per MySQL instance is appropriate (high CPU load, memory fully loaded, availability requirements).
But there are also those users who want to (or would like to) have multiple instances which would still fit into a single machine. Even among them, a single instance per machine is typical. For this, there are good reasons:
- MySQL comes with defaults for files (config file, error log, ...) and directories (data directory, binlogs, ...) which would cause conflicts between multiple instances (unless they are changed).
- The scripts coming with MySQL, especially the automated start/stop with machine reboot/shutdown, are written for a single instance only.
- Last but not least: The instructions. those in the manual as well as the many "How to setup ..." in the Web, cover a single instance only.
But that overhead (both in software and in labour) isn't necessary: There is a way out, supporting easy handling of multiple MySQL instances on a single machine directly, without containers or VMs. This is our "MyEnv" package, available for download here, licensed under the GPL.
What Does MyEnv Do?MyEnv cares about two aspects which in combination provide easy use of multiple instances:
- It helps to configure multiple MySQL instances without overlap, so they won't collide with each other.
- It maintains separate environments, each to manage and access one specific instance.
Each environment contains the path to the binaries (so the instances can use different versions), the config file, the socket and port number, data directory, error log etc. The environment is specified by a name (choose a meaningful one!), and it is switched by using its name as a shell command. (MyEnv creates an alias for that.)
Administrative commands like "start" and "stop" will manage the instance of the current environment. MySQL client programs like "mysql" or "mysqldump" will access that instance.
MyEnv supports the autostart of instances at machine boot, configurable per instance - something which is impossible using only the tools of a MySQL distribution.
Of course, an instance started via MyEnv (either manually or via autostart) can be accessed by any other client program on the machine, or from any other machine in the network - all that is needed is the specification of the proper socket or network port.
Handling Multiple Binaries
In the previous section, I wrote the instances can use different versions.
This is done by installing those different versions into different locations, controlled by MyEnv, and the directory with the binaries will become a component of the user's PATH variable, switched when the environment is switched.
Obviously, this works only if the destination path of the installation can be controlled, which implies the tar.gz format - RPM or DEB packages have fixed destinations, so different versions would overwrite each other on installation.
But that is no severe limitation, as all MySQL versions are available in tar.gz format, and these are sufficiently generic to run on any reasonably current Linux distribution.
(Yes, that is something I forgot to mention:
MyEnv is developed and tested on Linux only.
You are welcome to try it on any other Unix platform, and we will gladly listen to your experiences and accept your contributions, but we do not actively pursue non-Linux platforms.)
This support for multiple versions makes MyEnv the perfect tool for application development: Using a single machine, you can let your application access the MySQL servers of different versions and can verify it works the way you want it to.
Similar, you can install binaries of MySQL (Oracle), Percona Server, or MariaDB, and verify your application is portable across them.
And the adventurous among us can use different binaries, from the same or different vendor(s), to test whether replication works across versions and/or vendors, all without the effort of installing a separate VM or container setup.
MyEnv and Galera Cluster Till now, I mentioned MySQL (and its variants), and many readers may associate that term with a traditional single instance. So I better state explicitly: Of course, such an instance can take part in replication, in any role: master, slave, or intermediate in multi-level replication.But besides single instances and replication, there exists a different MySQL setup: Nodes combined to form a Galera Cluster. And again, let me state explicitly: Again of course, an instance controlled by MyEnv can be a node participating in a Galera Cluster.
Those readers who have experiance with Galera Cluster (or who have just read the documentation or blogs about it) know that to start the first node of a cluster a special command is needed, called "bootstrap" - a simple "start" will not do. So this command was also added to MyEnv, it can manage a Galera Cluster completely by its builtin commands.
RPM and DEB packages Above, I wrote that to install different versions you cannot use RPM or DEB packages. I did not write that MyEnv cannot use RPM or DEB - in fact it can, the absolute path names in these formats just limit this to a single version.So you can install the RPM or DEB of your choice, disable its autostart, and then call MyEnv to create multiple instances. You will give them different names, specify different sockets and ports and use different data directories, but for all of them you will specify the same path "/usr". As a result, MyEnv will simply manage multiple instances of the same version.
You can configure them differently to test the consequences, or you can set them up to replicate among them - master and slave can run on the same machine. Of course, this will not give you the "high availability" or the "scale-out" benefits which are the typical reasons to use replication, but I trust this wasn't your purpose for this test.
Using binaries that include Galera, and configuring them properly, you can even run all nodes of a Galera Cluster as separate instances on a single machine. That may be considered to stretch the concept, because a single machine is a very different setup than separate machines, but it gives an idea of the possibilities opened by MyEnv.
Typical Use of MyEnvAdmitted: The claim to know what MyEnv is used for by others would be arrogant, and I do not uphold it. Nonetheless, we do know some use cases of people who downloaded MyEnv, and they are close to our internal use of the tool.
MyEnv allows to have multiple MySQL instances on the same machine, to manage them separately, and to access them using MySQL client programs or other applications. So it is the perfect setup for all those who need to access different versions: developers and software testers.
When we encounter some unexpected behaviour, we often want to know whether it is specific to some version or series, or is widespread. To check that, MyEnv is the perfect infrastructure: You write a test case to provoke the effect and run it on several versions, then you note the result and can tell whether it exists "since ages" or is new, whether it still occurs in current versions or will change with an upgrade - exactly the information you need to decide about an upgrade or write a bug report.
Database administrators and application developers use it to avoid nasty surprises with new versions, so their production instances will not suffer from unexpected functional changes. Setting up a test environment, especially for multiple versions, becomes cheap, much less ressources are needed. You don't need to copy your test code onto different machines, and you are sure you are running identical tests, so that you won't compare apples and oranges.
InvitationIf all that made you curious, I invite you to look into the instructions, to download MyEnv and to try it. And of course, your feedback and reports are very welcome.
Take care!
Appendix: Where to Meet UsAll FromDual colleagues will deliver talks at the FrOSCon in St. Augustin near Cologne, Germany, on August 20 and 21, so that is a good opportunity for personal contact. As several talks will be delivered in English, the conference also meets the needs of attendants who cannot follow a German talk - check the programme. Froscon is a famous event, very interesting talks are promised, and I look forward to enjoy the community atmosphere there.
I will deliver a talk at the "Open Source Backup Conference" in Cologne, Germany, on September 26 and 27; this conference is held in English.
I do not have feedback yet about Percona Live in Amsterdam, I may attend that also.
And finally, FromDual will again have a booth and deliver talks at the DOAG conference on November 15 - 18 in Nuremberg, Germany. This is "the" event for Oracle users (at least in Germany, maybe in all Europe), and it has a separate track dealing with MySQL only.
We will be delighted to meet you face to face!
Taxonomy upgrade extras: MyEnvMultiple MySQL Instances on a Single Machine
Typically, on a single machine (be it a physical or a virtual one) only a single MySQL instance (process) is running. This is perfectly ok for all those situations where a single instance is sufficient, like for storing small amounts of data (RedHat using MySQL for postfix, KDE using it for akonadi, ...), as well as those where a dedicated machine per MySQL instance is appropriate (high CPU load, memory fully loaded, availability requirements).
But there are also those users who want to (or would like to) have multiple instances which would still fit into a single machine. Even among them, a single instance per machine is typical. For this, there are good reasons:
- MySQL comes with defaults for files (config file, error log, ...) and directories (data directory, binlogs, ...) which would cause conflicts between multiple instances (unless they are changed).
- The scripts coming with MySQL, especially the automated start/stop with machine reboot/shutdown, are written for a single instance only.
- Last but not least: The instructions. those in the manual as well as the many "How to setup ..." in the Web, cover a single instance only.
But that overhead (both in software and in labour) isn't necessary: There is a way out, supporting easy handling of multiple MySQL instances on a single machine directly, without containers or VMs. This is our "MyEnv" package, available for download here, licensed under the GPL.
What Does MyEnv Do?MyEnv cares about two aspects which in combination provide easy use of multiple instances:
- It helps to configure multiple MySQL instances without overlap, so they won't collide with each other.
- It maintains separate environments, each to manage and access one specific instance.
Each environment contains the path to the binaries (so the instances can use different versions), the config file, the socket and port number, data directory, error log etc. The environment is specified by a name (choose a meaningful one!), and it is switched by using its name as a shell command. (MyEnv creates an alias for that.)
Administrative commands like "start" and "stop" will manage the instance of the current environment. MySQL client programs like "mysql" or "mysqldump" will access that instance.
MyEnv supports the autostart of instances at machine boot, configurable per instance - something which is impossible using only the tools of a MySQL distribution.
Of course, an instance started via MyEnv (either manually or via autostart) can be accessed by any other client program on the machine, or from any other machine in the network - all that is needed is the specification of the proper socket or network port.
Handling Multiple Binaries
In the previous section, I wrote the instances can use different versions.
This is done by installing those different versions into different locations, controlled by MyEnv, and the directory with the binaries will become a component of the user's PATH variable, switched when the environment is switched.
Obviously, this works only if the destination path of the installation can be controlled, which implies the tar.gz format - RPM or DEB packages have fixed destinations, so different versions would overwrite each other on installation.
But that is no severe limitation, as all MySQL versions are available in tar.gz format, and these are sufficiently generic to run on any reasonably current Linux distribution.
(Yes, that is something I forgot to mention:
MyEnv is developed and tested on Linux only.
You are welcome to try it on any other Unix platform, and we will gladly listen to your experiences and accept your contributions, but we do not actively pursue non-Linux platforms.)
This support for multiple versions makes MyEnv the perfect tool for application development: Using a single machine, you can let your application access the MySQL servers of different versions and can verify it works the way you want it to.
Similar, you can install binaries of MySQL (Oracle), Percona Server, or MariaDB, and verify your application is portable across them.
And the adventurous among us can use different binaries, from the same or different vendor(s), to test whether replication works across versions and/or vendors, all without the effort of installing a separate VM or container setup.
MyEnv and Galera Cluster Till now, I mentioned MySQL (and its variants), and many readers may associate that term with a traditional single instance. So I better state explicitly: Of course, such an instance can take part in replication, in any role: master, slave, or intermediate in multi-level replication.But besides single instances and replication, there exists a different MySQL setup: Nodes combined to form a Galera Cluster. And again, let me state explicitly: Again of course, an instance controlled by MyEnv can be a node participating in a Galera Cluster.
Those readers who have experiance with Galera Cluster (or who have just read the documentation or blogs about it) know that to start the first node of a cluster a special command is needed, called "bootstrap" - a simple "start" will not do. So this command was also added to MyEnv, it can manage a Galera Cluster completely by its builtin commands.
RPM and DEB packages Above, I wrote that to install different versions you cannot use RPM or DEB packages. I did not write that MyEnv cannot use RPM or DEB - in fact it can, the absolute path names in these formats just limit this to a single version.So you can install the RPM or DEB of your choice, disable its autostart, and then call MyEnv to create multiple instances. You will give them different names, specify different sockets and ports and use different data directories, but for all of them you will specify the same path "/usr". As a result, MyEnv will simply manage multiple instances of the same version.
You can configure them differently to test the consequences, or you can set them up to replicate among them - master and slave can run on the same machine. Of course, this will not give you the "high availability" or the "scale-out" benefits which are the typical reasons to use replication, but I trust this wasn't your purpose for this test.
Using binaries that include Galera, and configuring them properly, you can even run all nodes of a Galera Cluster as separate instances on a single machine. That may be considered to stretch the concept, because a single machine is a very different setup than separate machines, but it gives an idea of the possibilities opened by MyEnv.
Typical Use of MyEnvAdmitted: The claim to know what MyEnv is used for by others would be arrogant, and I do not uphold it. Nonetheless, we do know some use cases of people who downloaded MyEnv, and they are close to our internal use of the tool.
MyEnv allows to have multiple MySQL instances on the same machine, to manage them separately, and to access them using MySQL client programs or other applications. So it is the perfect setup for all those who need to access different versions: developers and software testers.
When we encounter some unexpected behaviour, we often want to know whether it is specific to some version or series, or is widespread. To check that, MyEnv is the perfect infrastructure: You write a test case to provoke the effect and run it on several versions, then you note the result and can tell whether it exists "since ages" or is new, whether it still occurs in current versions or will change with an upgrade - exactly the information you need to decide about an upgrade or write a bug report.
Database administrators and application developers use it to avoid nasty surprises with new versions, so their production instances will not suffer from unexpected functional changes. Setting up a test environment, especially for multiple versions, becomes cheap, much less ressources are needed. You don't need to copy your test code onto different machines, and you are sure you are running identical tests, so that you won't compare apples and oranges.
InvitationIf all that made you curious, I invite you to look into the instructions, to download MyEnv and to try it. And of course, your feedback and reports are very welcome.
Take care!
Appendix: Where to Meet UsAll FromDual colleagues will deliver talks at the FrOSCon in St. Augustin near Cologne, Germany, on August 20 and 21, so that is a good opportunity for personal contact. As several talks will be delivered in English, the conference also meets the needs of attendants who cannot follow a German talk - check the programme. Froscon is a famous event, very interesting talks are promised, and I look forward to enjoy the community atmosphere there.
I will deliver a talk at the "Open Source Backup Conference" in Cologne, Germany, on September 26 and 27; this conference is held in English.
I do not have feedback yet about Percona Live in Amsterdam, I may attend that also.
And finally, FromDual will again have a booth and deliver talks at the DOAG conference on November 15 - 18 in Nuremberg, Germany. This is "the" event for Oracle users (at least in Germany, maybe in all Europe), and it has a separate track dealing with MySQL only.
We will be delighted to meet you face to face!
Temporary tables and MySQL STATUS information
When analysing MySQL configuration and status information at customers it is always interesting to see how the applications behave. This can partially be seen by the output of the SHOW GLOBAL STATUS command. See also Reading MySQL fingerprints.
Today we wanted to know where the high Com_create_table and the twice as high Com_drop_table is coming from. One suspect was TEMPORARY TABLES. But are real temporary tables counted as Com_create_table and Com_drop_table at all? This is what we want to find out today. The tested MySQL version is 5.7.11.
Caution: Different MySQL or MariaDB versions might behave differently!
Session 1 Global Session 2 CREATE TABLE t1 (id INT);Query OK, 0 rows affected Com_create_table +1
Opened_table_definitions +1 Com_create_table +1
Opened_table_definitions +1 CREATE TABLE t1 (id INT);
ERROR 1050 (42S01): Table 't1' already exists Com_create_table +1
Open_table_definitions +1
Open_tables +1
Opened_table_definitions +1
Opened_tables +1 Com_create_table + 1
Open_table_definitions +1
Open_tables +1
Opened_table_definitions +1
Opened_tables +1 CREATE TABLE t1 (id INT);
ERROR 1050 (42S01): Table 't1' already exists Com_create_table + 1 Com_create_table + 1 DROP TABLE t1;
Query OK, 0 rows affected Com_drop_table +1
Open_table_definitions -1
Open_tables -1 Com_drop_table +1
Open_table_definitions -1
Open_tables -1 DROP TABLE t1;
ERROR 1051 (42S02): Unknown table 'test.t1' Com_drop_table -1 Com_drop_table -1 CREATE TEMPORARY TABLE ttemp (id INT);
Query OK, 0 rows affected Com_create_table +1
Opened_table_definitions +2
Opened_tables +1 Com_create_table +1
Opened_table_definitions +2
Opened_tables +1 CREATE TEMPORARY TABLE ttemp (id INT);
ERROR 1050 (42S01): Table 'ttemp' already exists Com_create_table +1 Com_create_table +1 DROP TABLE ttemp;
Query OK, 0 rows affected Com_drop_table +1 Com_drop_table +1 CREATE TEMPORARY TABLE ttemp (id int);
Query OK, 0 rows affected CREATE TEMPORARY TABLE ttemp (id int);
Query OK, 0 rows affected Com_create_table +1
Opened_table_definitions +2
Opened_tables +1 Com_create_table +2
Opened_table_definitions +4
Opened_tables +2 Com_create_table +1
Opened_table_definitions +2
Opened_tables +1 DROP TABLE ttemp;
Query OK, 0 rows affected DROP TABLE ttemp;
Query OK, 0 rows affected Com_drop_table +1 Com_drop_table +2 Com_drop_table +1
Conclusion
- A successful CREATE TABLE command opens and closes a table definition.
- A non successful CREATE TABLE command opens the table definition and the file handle of the previous table. So a faulty application can be quite expensive.
- A further non successful CREATE TABLE command has no other impact.
- A DROP TABLE command closes a table definition and the file handle.
- A CREATE TEMPORARY TABLE opens 2 table definitions and the file handle. Thus behaves different than CREATE TABLE
- But a faulty CREATE TEMPORARY TABLE seems to be much less intrusive.
- Open_table_definitions and Open_tables is always global, also in session context.
Why is varchar(255) not varchar(255)?
Recently I was working on a clients question and stumbled over an issue with replication and mixed character sets. The client asked, wether it is possible to replicate data to a table on a MySQL slave, where one column had a different character set, than the column in the same table on the master.
I set up two servers with identical table definitions and changed the character set on one column on the slave from latin1 to utf8.
Master:
CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `data` varchar(255) DEFAULT NULL, `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Slave:
CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `data` varchar(255) CHARACTER SET utf8 DEFAULT NULL, `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
So far no problem, I was able to start the replication and set off some INSERT statements with special characters (like ä, ö, ü, ...). But when I went to look for them in the slave's table, I could not find them.
"SHOW SLAVE STATUS", showed me this error:
Column 1 of table 'test.test' cannot be converted from type 'varchar(255)' to type 'varchar(255)'
You might ask yourself now: But the columns have the same type, what is the problem? What is not shown in the error is the fact, that there are two different character sets.
The log file is of no help either. It only shows the same error and tells you to fix it.
2016-05-26 15:51:06 9269 [ERROR] Slave SQL: Column 1 of table 'test.test' cannot be converted from type 'varchar(255)' to type 'varchar(255)', Error_code: 1677 2016-05-26 15:51:06 9269 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'valkyrie_mysqld35701_binlog.000050' position 120 2016-05-26 15:53:39 9269 [ERROR] Error reading packet from server: Lost connection to MySQL server during query ( server_errno=2013)
Skipping the statement will not work, as the server will just fail again, when the next statement shows up.
For all those who are now running to change the character set: STOP!
Changing characters set of columns or tables containing data can be fatal when done incorrectly. MySQL offers a statement to convert tables and columns to the character set you wish to have.
To convert the entire table, you can write:
ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;
To convert a single column, you can write:
ALTER TABLE tbl_name MODIFY latin1_column TEXT CHARACTER SET utf8;
More details can be found in the ALTER TABLE documentation of MySQL. (Converting character sets is at the end of the article.)
Just to be clear, this is no bug! MySQL replication was never intended to work with mixed character sets and it makes a lot of sense, that the replication is halted when differences are discovered. This test was only an experiment.
Taxonomy upgrade extras: replicationcharacter setutf8utf8mb4Why is varchar(255) not varchar(255)?
Recently I was working on a clients question and stumbled over an issue with replication and mixed character sets. The client asked, wether it is possible to replicate data to a table on a MySQL slave, where one column had a different character set, than the column in the same table on the master.
I set up two servers with identical table definitions and changed the character set on one column on the slave from latin1 to utf8.
Master:
CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `data` varchar(255) DEFAULT NULL, `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Slave:
CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `data` varchar(255) CHARACTER SET utf8 DEFAULT NULL, `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
So far no problem, I was able to start the replication and set off some INSERT statements with special characters (like ä, ö, ü, ...). But when I went to look for them in the slave's table, I could not find them.
"SHOW SLAVE STATUS", showed me this error:
Column 1 of table 'test.test' cannot be converted from type 'varchar(255)' to type 'varchar(255)'
You might ask yourself now: But the columns have the same type, what is the problem? What is not shown in the error is the fact, that there are two different character sets.
The log file is of no help either. It only shows the same error and tells you to fix it.
2016-05-26 15:51:06 9269 [ERROR] Slave SQL: Column 1 of table 'test.test' cannot be converted from type 'varchar(255)' to type 'varchar(255)', Error_code: 1677 2016-05-26 15:51:06 9269 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'valkyrie_mysqld35701_binlog.000050' position 120 2016-05-26 15:53:39 9269 [ERROR] Error reading packet from server: Lost connection to MySQL server during query ( server_errno=2013)
Skipping the statement will not work, as the server will just fail again, when the next statement shows up.
For all those who are now running to change the character set: STOP!
Changing characters set of columns or tables containing data can be fatal when done incorrectly. MySQL offers a statement to convert tables and columns to the character set you wish to have.
To convert the entire table, you can write:
ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;
To convert a single column, you can write:
ALTER TABLE tbl_name MODIFY latin1_column TEXT CHARACTER SET utf8;
More details can be found in the ALTER TABLE documentation of MySQL. (Converting character sets is at the end of the article.)
Just to be clear, this is no bug! MySQL replication was never intended to work with mixed character sets and it makes a lot of sense, that the replication is halted when differences are discovered. This test was only an experiment.
Why is varchar(255) not varchar(255)?
Recently I was working on a clients question and stumbled over an issue with replication and mixed character sets. The client asked, wether it is possible to replicate data to a table on a MySQL slave, where one column had a different character set, than the column in the same table on the master.
I set up two servers with identical table definitions and changed the character set on one column on the slave from latin1 to utf8.
Master:
CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `data` varchar(255) DEFAULT NULL, `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Slave:
CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `data` varchar(255) CHARACTER SET utf8 DEFAULT NULL, `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
So far no problem, I was able to start the replication and set off some INSERT statements with special characters (like ä, ö, ü, ...). But when I went to look for them in the slave's table, I could not find them.
"SHOW SLAVE STATUS", showed me this error:
Column 1 of table 'test.test' cannot be converted from type 'varchar(255)' to type 'varchar(255)'
You might ask yourself now: But the columns have the same type, what is the problem? What is not shown in the error is the fact, that there are two different character sets.
The log file is of no help either. It only shows the same error and tells you to fix it.
2016-05-26 15:51:06 9269 [ERROR] Slave SQL: Column 1 of table 'test.test' cannot be converted from type 'varchar(255)' to type 'varchar(255)', Error_code: 1677 2016-05-26 15:51:06 9269 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'valkyrie_mysqld35701_binlog.000050' position 120 2016-05-26 15:53:39 9269 [ERROR] Error reading packet from server: Lost connection to MySQL server during query ( server_errno=2013)
Skipping the statement will not work, as the server will just fail again, when the next statement shows up.
For all those who are now running to change the character set: STOP!
Changing characters set of columns or tables containing data can be fatal when done incorrectly. MySQL offers a statement to convert tables and columns to the character set you wish to have.
To convert the entire table, you can write:
ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;
To convert a single column, you can write:
ALTER TABLE tbl_name MODIFY latin1_column TEXT CHARACTER SET utf8;
More details can be found in the ALTER TABLE documentation of MySQL. (Converting character sets is at the end of the article.)
Just to be clear, this is no bug! MySQL replication was never intended to work with mixed character sets and it makes a lot of sense, that the replication is halted when differences are discovered. This test was only an experiment.
FromDual Schulung 2016 für MySQL und MariaDB
Aufgrund der zunehmenden Nachfrage nach MariaDB Know-How legen wir bei unseren Schulungen vermehrt Wert darauf, sowohl MySQL als auch MariaDB zu behandeln.
Neue Schulungsstandorte - Köln, Frankfurt und ZürichDank der Zusammenarbeit mit zwei neuen Schulungsinfrastruktur-Partnern, den Firmen Trivadis GmbH und GFU Cyrus AG, können wir Ihnen jetzt unsere bewährten FromDual Schulungen auch an den Standorten Köln, Frankfurt und Zürich anbieten.
MySQL/MariaDB für Einsteiger und EntwicklerFür das Jahr 2016 haben wir auch unser Schulungs-Angebot erweitert. Neu bietet FromDual auch eine Schulung MySQL/MariaDB für Einsteiger sowie MySQL/MariaDB für Entwickler an.
Eine detaillierte Übersicht über unser Schulungsangebot finden Sie hier.
FromDual SchulungstermineEine Übersicht über die geplanten Schulungstermine finden Sie hier.
Taxonomy upgrade extras: schulungmysql-trainingtrainingmysql-schulungFromDual Schulung 2016 für MySQL und MariaDB
Aufgrund der zunehmenden Nachfrage nach MariaDB Know-How legen wir bei unseren Schulungen vermehrt Wert darauf, sowohl MySQL als auch MariaDB zu behandeln.
Neue Schulungsstandorte - Köln, Frankfurt und ZürichDank der Zusammenarbeit mit zwei neuen Schulungsinfrastruktur-Partnern, den Firmen Trivadis GmbH und GFU Cyrus AG, können wir Ihnen jetzt unsere bewährten FromDual Schulungen auch an den Standorten Köln, Frankfurt und Zürich anbieten.
MySQL/MariaDB für Einsteiger und EntwicklerFür das Jahr 2016 haben wir auch unser Schulungs-Angebot erweitert. Neu bietet FromDual auch eine Schulung MySQL/MariaDB für Einsteiger sowie MySQL/MariaDB für Entwickler an.
Eine detaillierte Übersicht über unser Schulungsangebot finden Sie hier.
FromDual SchulungstermineEine Übersicht über die geplanten Schulungstermine finden Sie hier.
Taxonomy upgrade extras: schulungmysql-trainingtrainingmysql-schulungFromDual Schulung 2016 für MySQL und MariaDB
Aufgrund der zunehmenden Nachfrage nach MariaDB Know-How legen wir bei unseren Schulungen vermehrt Wert darauf, sowohl MySQL als auch MariaDB zu behandeln.
Neue Schulungsstandorte - Köln, Frankfurt und ZürichDank der Zusammenarbeit mit zwei neuen Schulungsinfrastruktur-Partnern, den Firmen Trivadis GmbH und GFU Cyrus AG, können wir Ihnen jetzt unsere bewährten FromDual Schulungen auch an den Standorten Köln, Frankfurt und Zürich anbieten.
MySQL/MariaDB für Einsteiger und EntwicklerFür das Jahr 2016 haben wir auch unser Schulungs-Angebot erweitert. Neu bietet FromDual auch eine Schulung MySQL/MariaDB für Einsteiger sowie MySQL/MariaDB für Entwickler an.
Eine detaillierte Übersicht über unser Schulungsangebot finden Sie hier.
FromDual SchulungstermineEine Übersicht über die geplanten Schulungstermine finden Sie hier.
Taxonomy upgrade extras: schulungmysql-trainingtrainingmysql-schulungMySQL spatial functionality - points of interest around me
This week I was preparing the exercises for our MySQL/MariaDB for Beginners training. One of the exercises of the training is about MySQL spatial (GIS) features. I always tell customers: "With these features you can answer questions like: Give me all points of interest around me!"
Now I wanted to try out how it really works and if it is that easy at all...
To get myself an idea of what I want to do I did a little sketch first:
My position Shops Restaurants CafesTo do this I needed a table and some data:
CREATE TABLE poi ( id INT UNSIGNED NOT NULL AUTO_INCREMENT , name VARCHAR(40) , type VARCHAR(20) , sub_type VARCHAR(20) , pt POINT NOT NULL , PRIMARY KEY (id) , SPATIAL INDEX(pt) ) ENGINE=InnoDB; INSERT INTO poi (name, type, sub_type, pt) VALUES ('Shop 1', 'Shop', 'Cloth', Point(2,2)) , ('Cafe 1', 'Cafe', '', Point(11,2)) , ('Shop 2', 'Shop', 'Cloth', Point(5,4)) , ('Restaurant 1', 'Restaurant', 'Portugies', Point(8,7)) , ('Cafe 2', 'Cafe', '', Point(3,9)) , ('Shop 3', 'Shop', 'Hardware', Point(11,9)) ;This looks as follows:
SELECT id, CONCAT(ST_X(pt), '/', ST_Y(pt)) AS "X/Y", name, type, sub_type FROM poi; +----+-----------+--------------+------------+-----------+ | id | X/Y | name | type | sub_type | +----+-----------+--------------+------------+-----------+ | 1 | 2/2 | Shop 1 | Shop | Cloth | | 2 | 11/2 | Cafe 1 | Cafe | | | 3 | 5/4 | Shop 2 | Shop | Cloth | | 4 | 8/7 | Restaurant 1 | Restaurant | Portugies | | 5 | 3/9 | Cafe 2 | Cafe | | | 6 | 11/9 | Shop 3 | Shop | Hardware | +----+-----------+--------------+------------+-----------+Now the question: "Give me all shops in a distance of 4.5 units around me":
SET @hereami = POINT(9,4); SELECT id, ST_AsText(pt) AS point, name, ROUND(ST_Distance(@hereami, pt), 2) AS distance FROM poi WHERE ST_Distance(@hereami, pt) < 4.5 AND type = 'Shop' ORDER BY distance ASC ; +----+------------+--------+----------+ | id | point | name | distance | +----+------------+--------+----------+ | 3 | POINT(5 4) | Shop 2 | 4.00 | +----+------------+--------+----------+ 1 row in set (0.37 sec)The query execution plan looks like this:
id: 1 select_type: SIMPLE table: poi partitions: NULL type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 650361 filtered: 10.00 Extra: Using where; Using filesortSo no use of the spatial index yet. :-(
Reading the MySQL documentation Using Spatial Indexes provides some more information:
The optimizer investigates whether available spatial indexes can be involved in the search for queries that use a function such as MBRContains() or MBRWithin() in the WHERE clause.
So it looks like the optimizer CAN evaluate function covered fields in this specific case. But not with the function ST_Distance I have chosen.
So my WHERE clause must look like: "Give me all points within a polygon spanned 4.5 units around my position..."
I did not find any such function in the short run. So I created a hexagon which is not too far from a circle...
With this hexagon I tried again:
SET @hereami = POINT(9,4); SET @hexagon = 'POLYGON((9 8.5, 12.897 6.25, 12.897 1.75, 9 -0.5, 5.103 1.75, 5.103 6.25, 9 8.5))'; SELECT id, ST_AsText(pt) AS point, name, ROUND(ST_Distance(@hereami, pt), 2) AS distance FROM poi WHERE MBRContains(ST_GeomFromText(@hexagon), pt) AND ST_Distance(@hereami, pt) < 4.5 AND type = 'Shop' ORDER BY distance ASC ; Empty set (0.03 sec)And tadaaah: Damned fast, but the result is not the same! :-( When you look at the graph above it is obvious why: The missing shop is 0.103 units outside of our hexagon search range but within our circle range. So an octagon would have been the better approach...
At least the index is considered now! :-)
id: 1 select_type: SIMPLE table: poi partitions: NULL type: range possible_keys: pt key: pt key_len: 34 ref: NULL rows: 31356 filtered: 10.00 Extra: Using where; Using filesortFor specifying a an "outer" hexagon I was too lazy. So I was specifying a square:
SET @hereami = POINT(9,4); SET @square = 'POLYGON((4.5 8.5, 13.5 8.5, 13.5 -0.5, 4.5 -0.5, 4.5 8.5))'; SELECT id, ST_AsText(pt) AS point, name, ROUND(ST_Distance(@hereami, pt), 2) AS distance FROM poi WHERE MBRContains(ST_GeomFromText(@square), pt) AND ST_Distance(@hereami, pt) < 4.5 AND type = 'Shop' ORDER BY distance ASC ; +----+------------+--------+----------+ | id | point | name | distance | +----+------------+--------+----------+ | 3 | POINT(5 4) | Shop 2 | 4.00 | +----+------------+--------+----------+ 1 row in set (0.02 sec)So, my shop is in the result again now. And even a bit faster!
Now I wanted to find out if this results are any faster than the conventional method with an index on (x) and (y) or (x, y):
SELECT id, ST_AsText(pt) AS point, name, ROUND(ST_Distance(@hereami, pt), 2) AS distance FROM poi WHERE x >= 4.5 AND x <= 13.5 AND y >= -0.5 AND y <= 8.5 AND ST_Distance(@hereami, pt) < 4.5 AND type = 'Shop' ORDER BY distance ASC ; 1 row in set (0.15 sec)Here the optimizer chooses the index on x. But I think he could do better. So I forced to optimizer to use the index on (x, y):
SELECT id, ST_AsText(pt) AS point, name, ROUND(ST_Distance(@hereami, pt), 2) AS distance FROM poi FORCE INDEX (xy) WHERE x >= 4.5 AND x <= 13.5 AND y >= -0.5 AND y <= 8.5 AND ST_Distance(@hereami, pt) < 4.5 AND type = 'Shop' ORDER BY distance ASC ; 1 row in set (0.03 sec) id: 1 select_type: SIMPLE table: poi partitions: NULL type: range possible_keys: xy key: xy key_len: 10 ref: NULL rows: 115592 filtered: 1.11 Extra: Using index condition; Using where; Using filesortSame performance than with the spatial index. So it looks like for this simple task with my data distribution conventional methods do well enough.
No I wanted to try a polygon which comes as close as possible to a circle. This I solved with a MySQL stored function which returns a polygon:/p>
DROP FUNCTION polygon_circle; delimiter // CREATE FUNCTION polygon_circle(pX DOUBLE, pY DOUBLE, pDiameter DOUBLE, pPoints SMALLINT UNSIGNED) -- RETURNS VARCHAR(4096) DETERMINISTIC RETURNS POLYGON DETERMINISTIC BEGIN DECLARE i SMALLINT UNSIGNED DEFAULT 0; DECLARE vSteps SMALLINT UNSIGNED; DECLARE vPolygon VARCHAR(4096) DEFAULT ''; -- Input validation IF pPoints < 3 THEN RETURN NULL; END IF; IF pPoints > 360 THEN RETURN NULL; END IF; IF pPoints > 90 THEN RETURN NULL; END IF; if (360 % pPoints) != 0 THEN RETURN NULL; END IF; -- Start SET vSteps = 360 / pPoints; WHILE i < 360 DO SET vPolygon = CONCAT(vPolygon, (pX + (SIN(i * 2 * PI() / 360) * pDiameter)), ' ', (pY + (COS(i * 2 * PI() / 360) * pDiameter)), ', '); SET i = i + vSteps; END WHILE; -- Add first point again SET vPolygon = CONCAT("POLYGON((", vPolygon, (pX + (SIN(0 * 2 * PI() / 360) * pDiameter)), " ", (pY + (COS(0 * 2 * PI() / 360) * pDiameter)), "))"); -- RETURN vPolygon; RETURN ST_GeomFromText(vPolygon); END; // delimiter ; SELECT ST_AsText(polygon_circle(9, 4, 4.5, 6)); -- SELECT polygon_circle(9, 4, 4.5, 8);Then calling the query in the same way:
SET @hereami = POINT(9,4); SELECT id, ST_AsText(pt) AS point, name, ROUND(ST_Distance(@hereami, pt), 2) AS distance FROM poi WHERE MBRContains(polygon_circle(9, 4, 4.5, 90), pt) AND ST_Distance(@hereami, pt) < 4.5 AND type = 'Shop' ORDER BY distance ASC ; +----+------------+--------+----------+ | id | point | name | distance | +----+------------+--------+----------+ | 3 | POINT(5 4) | Shop 2 | 4.00 | +----+------------+--------+----------+ 1 row in set (0.03 sec)This seems not to have any significant negative impact on performance.
Results Test#rowsoperationlatencyTotal655360FTS1300 msSpatial exact Circle4128FTS520 msSpatial inner Hexagon3916range (pt)20 msSpatial outer Square4128range (pt)30 msConventional outer Square on (x)4128range (x) or (y)150 msConventional outer Square on (xy)4128range (x,y)30 msSpatial good Polygon4128range (pt)30 msTaxonomy upgrade extras: spatialgisWhy you should take care of MySQL data types
A customer reported last month that MySQL does a full table scan (FTS) if a query was filtered by a INT value on a VARCHAR column. First I told him that this is not true any more because MySQL has fixed this behaviour long time ago. He showed me that I was wrong:
CREATE TABLE `test` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `data` varchar(64) DEFAULT NULL, `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `data` (`data`) ) ENGINE=InnoDB; EXPLAIN SELECT * FROM test WHERE data = 42\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test partitions: NULL type: ALL possible_keys: data key: NULL key_len: NULL ref: NULL rows: 522500 filtered: 10.00 Extra: Using where EXPLAIN SELECT * FROM test WHERE data = '42'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test partitions: NULL type: ref possible_keys: data key: data key_len: 67 ref: const rows: 1 filtered: 100.00 Extra: NULLWhen I executed the query I got some more interesting information:
SELECT * FROM test WHERE data = '42'; Empty set (0.00 sec) SELECT * FROM test WHERE data = 42; +--------+----------------------------------+---------------------+ | id | data | ts | +--------+----------------------------------+---------------------+ | 1096 | 42a5cb4a3e76857a3efe7af44ba9f4dd | 2016-05-25 10:26:59 | ... | 718989 | 42a1921fb2df42126d85f9586532eda4 | 2016-05-25 10:27:12 | +--------+----------------------------------+---------------------+ 767 rows in set, 65535 warnings (0.26 sec)Looking at the warnings we also find the reason: MySQL does the cast on the column and not on the value which is a bit odd IMHO:
show warnings; | Warning | 1292 | Truncated incorrect DOUBLE value: '80f52706c2f9de40472ec29a7f70c992' |A bit suspicious I looked at the warnings of the query execution plan again:
show warnings; +---------+------+---------------------------------------------------------------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------------------------------------------------------------+ | Warning | 1739 | Cannot use ref access on index 'data' due to type or collation conversion on field 'data' | | Warning | 1739 | Cannot use range access on index 'data' due to type or collation conversion on field 'data' | +---------+------+---------------------------------------------------------------------------------------------+I thought this was fixed, but it seems not. The following releases behave like this: MySQL 5.0.96, 5.1.73, 5.5.38, 5.6.25, 5.7.12 and MariaDB 5.5.41, 10.0.21 and 10.1.9
The other way around it seems to work in both cases:
SELECT * FROM test WHERE id = 42; +----+----------------------------------+---------------------+ | id | data | ts | +----+----------------------------------+---------------------+ | 42 | 81d74057d7be8f20563da404bb1b3ab0 | 2016-05-25 10:26:56 | +----+----------------------------------+---------------------+ SELECT * FROM test WHERE id = '42'; +----+----------------------------------+---------------------+ | id | data | ts | +----+----------------------------------+---------------------+ | 42 | 81d74057d7be8f20563da404bb1b3ab0 | 2016-05-25 10:26:56 | +----+----------------------------------+---------------------+ EXPLAIN SELECT * FROM test WHERE id = 42\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test partitions: NULL type: const possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: const rows: 1 filtered: 100.00 Extra: NULLTaxonomy upgrade extras: query tuningexplaindata typesql
DOAG Datenbank Konferenz 2016
Heute war ich auf der DOAG Datenbank 2016 Konferenz in Düsseldorf. Der einzige Vortrag zum Thema MySQL war mein eigener: MySQL für Oracle DBAs. Daher hatte ich die Möglichkeit wieder mal etwas über den Zaun zu linsen. Hier meine Notizen:
Oracle Database in-Memory - What's new and what's commingVon Andy Rivenes, Senior Principal Product Manager, Oracle Corporation
- Ist NICHT eine one size fits all Lösung.
- Für Analytics-Abfragen (DWH, Datamart, BI).
- Beschleunigt OLTP Workload NICHT.
- Ist ein Column-Store.
- In-Memory heisst: weiteren Cache (RAM). Mehr Speicher (RAM) hinzufügen. Column-Store Size. Daten werden partiell doppelt vorgehalten.
- Beide Formate Row und Column sind vorhanden.
- Optimizer entscheidet ob Row-Store oder Column-Store verwendet wird.
- Wird vom DBA pro Tabelle, Partition, Subpartition oder Materialized View festgelegt. 2 - 20 x Kompression.
- Column-Store wird on demand aufgebaut. Wenn nicht verfügbar, fallback auf Row-Store.
- Column-Store Advisor.
- Jeder Core scannt eine Spalte aus dem Column-Store.
- Geschwindigkeit: Mia rows/s. Wenn man bedenkt, dass ein Core nur ca. 3 Mia CPU Zyklen pro Sekunde hat, frage ich mich, wie das gerechnet wird...
- Eliminiere Indices und nutze Column-Store für grosse OLAP Tabellen.
- Schreiben ist langsam. Wie kriegt man denn die Daten schnell in die DB bei grossen Datenmengen?
- Scale-out und Scale-Up: Parallelisieren über mehrere Server hinweg.
- Spiegeln von Duplikaten über Server hinweg. Somit können Joins lokal gemacht werden.
- In-Memory Workload on (Oracle) Chips möglich: DAX, Database Accelleration Engine.
- JSON BLOB.
- Heatmap: Schlaue Guestimates (in der Zukunft).
- When not to use Oracle in-Memory Database: Siehe Slides.
Die Folien muss ich mir noch organisieren. Klingt total cool. Ich frage mich nur, wie gross/breit ist dieser Anwendungsfall? Ich werde mich wohl bald mal mit dem MariaDB Column Store befassen müssen/wollen.
Oracle ACFS / CloudFS zuverlässig nutzbar?Ralf Appelbaum und Claudia Gabriel, TEAM GmbH
- CFS im ASM
- ACFS = ASM CFS
- für RAC
- ASM ~ LVM
- TS im ASM (somit erinnert mich das ein bissen an etwas clevere Raw-Devices).
- Backup, Dumps, etc. ins ACFS. Somit sind sie O/S sichtbar und zugreifbar.
- Fazit war: Nein, ist es nicht!
Ich frage mich nur, warum, man sich das antun will...? Das ist nur wieder ein neues proprietäres Feature, welches nicht KISS ist!
Datenbanken in der Oracle Cloud - Überblick und Best PracticesManuel Hossfeld, Oracle Deutschland B.V. & Co KG
- Oracle Cloud ist eine Public Cloud.
- Arbeitet nur mit ssh Keys.
- SQL*Net über ssh-Tunnel. Will man das? Kann den SQL*Net kein SSL???
- Keine Hybrid-Cloud damit machen!
- Managed MySQL in der Oracle Cloud ist immer noch nicht vorgesehen.
- Einsatzgebiete: Er sprach nie von produktiver Nutzung...
Wozu braucht man das?
cgroups im Einsatz - Ressource Management mal anders rumFlorian Feicht, Trivadis GmbH
- Oracle selber scheint das vorzusehen. Siehe Oracle Dokumentation.
- systemd-cgtop
- systemd-cgls
- Oracle init.ora Parameter processor_group_name
- systemd/code> service!
- Oracle schreibt ins Alert Log, wenn es nicht klappt. Die Oracle Oracle Instanz fährt nicht hoch, wenn man die Cgroup nicht angelegt hat.
Die Oracle Cracks fanden das cool, hatten aber einige Bedenken (betreffen Optimizer und so). MyEnv für MySQL und MariaDB kann das schon seit Oktober 2014. Wir sind also gut vorn mit dabei.
Taxonomy upgrade extras: mysqlOraclein-memorymemorycgroups