MySQL collation server variables user dependent? - mysql

Connecting with different SQL users with the same client (Sequel Pro) on the same MySQL server on the same database results in different collation server variables.
In my.cnf, I included the following:
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci, NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
Connecting with user A results in:
collation_connection = utf8_unicode_ci
collation_database = utf8_unicode_ci
collation_server = utf8_unicode_ci
init_connect = SET collation_connection = utf8_unicode_ci, NAMES utf8
Connecting with user B results in:
collation_database = utf8_unicode_ci
collation_server = utf8_unicode_ci
init_connect = SET collation_connection = utf8_unicode_ci, NAMES utf8
So the collation_connection variable is missing. Is it possible the init_connect is ignored / user specific for some reason?
Because the collation_connection is not set, a Illegal mix of collations error occurs.

Possible cause: The init_connect string seems to be wrong. Try:
init_connect='SET collation_connection = utf8_unicode_ci; SET NAMES utf8;'
and then restart the mysql service.
This does not explain the weird behaviour with the SUPER permission however..

Please be aware that init_connect is not run when a user with SUPER privileges logs in. This is a security feature, as documented:
The content of init_connect is not executed for users that have the SUPER privilege. This is done so that an erroneous value for init_connect does not prevent all clients from connecting.
This is to prevent from locking yourself out of the database completely:
For example, the value might contain a statement that has a syntax error, thus causing client connections to fail. Not executing init_connect for users that have the SUPER privilege enables them to open a connection and fix the init_connect value.
So it is expected behavior for these users not to have this variable set upon connecting.

Related

mysql_install_db wrong charset and collation

I am creating a new server with the mysql_install_db tool. It sets the correct datadir, port, password, service etc. But My problem is that the charset and collation of my base tables are wrong. They need to be utf8mb4 and utf8mb4_general_ci.
I can't find a way to change these tables with the installation. When I change my.cnf/my.ini it only changes for newly created databases. But Since mysql_install_db creates the system databases, they are created wrong.
It also looks like my msyql_install_db.exe does not accept a defaults-file argument.
Something else is also weird. If I run the command to create a new database, it will also use utf8mb3 while I explicitly set the COLLATE to utf8mb4_unicode_ci.
CREATE DATABASE IF NOT EXISTS tt DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
I am using mariadb 10.6.4 which is the latest version.
Anyone knows how to setup the correct charset and collation to the system databases?
Tools\mariadb-winx64\bin\mysql_install_db.exe --datadir="Tools\mariadb-data" --password=PASSWORD --port=8137 --service=MyDB
[Update]
I tried to setup my.cnf with the following, but seems to take no effect: Change MySQL default character set to UTF-8 in my.cnf?
Also tried using a different way with initializing-insecure, but also the same results. I created a my.cnf with the correct encoding, but still got the wrong table encoding:
mariadb-winx64\bin\mariadbd.exe --defaults-file=./my.cnf --initialize-insecure --datadir=./Test
And my.cnf
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
skip-grant-tables
port = 5137
collation-server = utf8mb4_unicode_ci
init-connect='SET NAMES utf8mb4'
character-set-server = utf8mb4

Not all character sets and collation sets change to utf8mb4(.unicode.ci)

I am trying to set character sets to utf8mb4 and collation sets to utf8mb4_unicode_ci. On my website the emoji's looks fine when I get the data out of the table with php/mysql select. Only in phpMyAdmin (4.8.4) I see most emoji's as one questionamrk.
I try this:
Add to /etc/my.cnf:
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
Restart systemctl restart mariadb
I use on my website mysqli_set_charset($con, "utf8mb4");, <form accept-charset="UTF-8"> and <meta charset="utf-8">.
Result of SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%':
What am I doing wrong?
I use mysql version 5.5.60 (Mariadb).
Edit:
The problem might be phpmyadmin (4.8.4). It seems that phpMyAdmin is still using utf8. The global variabelen are set to utf8mb4 or utf8mb4_unicode_ci but I can't change the session variabelen:
I set in config.inc.php:
In the 'normal' table in phpMyAdmin:
And when I try SET NAMES everything looks fine:
Under General settings in phpMyAdmin the server connection collation is set on utf8_unicode_ci. I can select utf8mb4_unicode_ci, but then it switches back to utf8_unicode_ci :(
And on my website with select everything looks oké:

MySQL only storing some Emojis in text field when using UTF8MB4

We have a project where we're storing Facebook and Twitter posts in a Mysql database, as first almost all Emojis were being stored as ?. We've since gone ahead and made some configuration changes to the database server, and since then we're starting to see more Emojis saving and appearing correctly, however some Emojis are still showing as ?, sadly I'm not sure which ones they are. I know one of them was a basket ball.
When I execute the following commend on MySQL;
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%'
OR Variable_name LIKE 'collation%';
I see the following settings;
character_set_client = utf8
character_set_connection = utf8
character_set_database = utf8mb4
character_set_filesystem = binary
character_set_results = utf8
character_set_server = utf8mb4
character_set_system = utf8
collation_connection = utf8_general_ci
collation_database = utf8mb4_unicode_ci
collation_server = utf8mb4_unicode_ci
Our database server is hosted with Rackspace, we've asked them to set up the following configuration;
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init-connect='SET NAMES utf8mb4'
I've tested output from the database using a number of clients, PHP, Java and MySQL Workbench.
I'm at a loss now as to why some Emojis are not saving, and I've followed as much advice as I can find on the web.
character_set_client/connection/results = utf8 -- These three are changed by SET NAMES. What you list seems to be before SET NAMES is executed.
If you are connecting as root, init-connect is not executed; perhaps this is why you don't see it.
Establish a non-SUPER user for all application work; that way the init-connect will be executed.

How to change the connection collation of Mysql

How can I change connection collation of mysql database?
I am using Mysql workbench 5.5 and mysql 5.5 in ubuntu 14.
When I execute a stored procedure, an error occurs:
Error Code: 1267. Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation '='
I have search though the internet, which has a temp solution that is to amend
COLLATE utf8_unicode_ci;
in the stored procedure.
But I want to fix this problem for all stored procedures in the future. I have found
SHOW VARIABLES LIKE 'collation%';
which return this.
collation_connection utf8_general_ci
collation_database utf8_unicode_ci
collation_server latin1_swedish_ci
how can I change utf8_general_ci to utf8_unicode_ci?
Look into your my.cnf, find the contents below near collation_server:
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
Then change your collation variables to:
collation_connection utf8_unicode_ci
collation_server latin1_swedish_ci
Remember to restart MySQL server service.
For DB collation, you can use the following SQL:
ALTER DATABASE <database_name> CHARACTER SET utf8 COLLATE utf8_unicode_ci;
or you can do it at Alter database screen in MySQL Workbench (always update this to the latest version!)
Firstly, I think the error message is because of the collation of stored procedure (connection) doesn't match the table. But I was wrong, the reason for the error is because of the collation of the column doesn't match the collation of the table.
I want to change to collation of column to 'utf8_unicode_ci' in my case. So
I have run this statement:
alter table <YourTableName>
MODIFY <YourColumnName> VARCHAR(XXX) COLLATE 'utf8_unicode_ci';
Please be aware that change of collation may result in data loss. For me, General -> Unicode, with all English in varchar column. There is none.
Further reading:
http://dev.mysql.com/doc/refman/5.7/en/charset-column.html
http://dev.mysql.com/doc/refman/5.7/en/charset-connection.html
http://dev.mysql.com/doc/refman/5.7/en/charset-database.html

character-set-server VS default-character-set in MySQL

What's the difference between character-set-server and default-character-set in my.cnf? I want to set MySQL's connection to UTF8 and both of these seem to work. Is one better than the other?
Always use
character-set-server
The server character set and collation are used as default values if the database character set and collation are not specified in CREATE DATABASE statements. They have no other purpose (source)
character-set-server has replaced default-character-set setting, since default-character-set is now deprecated and can cause problems.
p.s. I believe the answer by newtover is wrong.
Here is a quote from MySQL docs:
You can force client programs to use specific character set as follows:
[client]
default-character-set=charset_name
This is normally unnecessary. However, when character_set_system differs from character_set_server or character_set_client, and you input characters manually (as database object identifiers, column values, or both), these may be displayed incorrectly in output from the client or the output itself may be formatted incorrectly. In such cases, starting the mysql client with --default-character-set=system_character_set—that is, setting the client character set to match the system character set—should fix the problem.
In other words, character_set_server and character_set_client are settings for mysqld, when default-character-set is a setting for mysql and other client libraries which overrides character_set_client assumed by mysqld by default.
You may not see the difference if you connect with mysql to localhost, but default-character-set is used as well when you connect to some other server, which may have other defaults.
UPD from 2018-08-17
As John Smith noticed, my answer is currently outdated, but the essence of it is still correct: character_set_server is a server variable, but when you connect to the mysqld with a client, you should specify the client and connection settings.
In these days much many computers used as clients and servers have utf-8 as a default for locale encoding and only because of that setting character-set-server instead of default-character-set might seem to work.
To be clear, to set up mysqld (that is server) to use utf-8 and some its collation as default for schema names, table names, column names and column values instead of latin1_swedish_ci you should set up characted-set-server in mysqld configuration.
But when you connect a mysql client to the server, your current charset may be any other, and to correctly convert to the server character set the data you send over a connection and to convert back the data sent from the server as response, you should specify the corresponding client settings:
SET character_set_client = charset_name;
SET character_set_results = charset_name;
SET character_set_connection = charset_name;
or the corresponding settings in mysql.ini for your client application. If all of them are the same, you can start your communication with server with a shorter statement:
SET NAMES 'charset_name' [COLLATE 'collation_name'];