create table as select working even with enforce-gtid-consistency - mysql

I have a sql script that contains the statement create tbl2 as select * from tbl;
This statement works on a docker mysql with version 5.7 (currently 5.7.19), even though enforce-gtid-consistency is turned on. Relevant lines from the docker compose yml are:
image: mysql:5.7
command: --gtid-mode=ON --enforce-gtid-consistency=true
This is even though the documentation clearly specifies:
Since only transactionally safe statements can be logged when --enforce-gtid-consistency is enabled, it follows that the operations listed here cannot be used with this option:
CREATE TABLE ... SELECT statements
The same statement fails with ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT. on a google cloud mysql instance.
show variables like '%gtid%' returns the same result on the docker mysql and the google cloud instance (and enforce_gtid_consistency is on in both).

Primary reason for failure you see is log-bin is NULL in container database though gtid_mode is on and enforce_gtid_consistency is on. So you must run container with log-bin set , setting this additionally also require to set server-id. Below is one example to run container where you should be able to reproduce error - "
ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT.
"
docker run -d --name=my-mysql --env="MYSQL_ROOT_PASSWORD=rootpassword123" --publish 3306:3306 --volume=/u01/mysql:/var/lib/mysql mysql/mysql-server:5.7.20 --gtid_mode=ON --enforce_gtid_consistency=ON --log-bin=mysql-bin --master-info-repository=table --relay-log-info-repository=table --server-id=1
cheers
raj

Related

How to solve "ERROR 1364 (HY000): Field 'Item_name' doesn't have a default value" [duplicate]

My table looks like
create table try ( name varchar(8), CREATED_BY varchar(40) not null);
and then I have a trigger to auto populate the CREATED_BY field
create trigger autoPopulateAtInsert BEFORE INSERT on try for each row set new.CREATED_BY=user();
When I do an insert using
insert into try (name) values ('abc');
the entry is made in the table but I still get the error message
Field 'CREATED_BY' doesn't have a default value Error no 1364
Is there a way to suppress this error without making the field nullable AND without removing the triggfer? Otherwise my hibernate will see these exceptions ( even though the insertions have been made) and then application will crash.
This is caused by the STRICT_TRANS_TABLES SQL mode defined in the
%PROGRAMDATA%\MySQL\MySQL Server 5.6\my.ini
file. Removing that setting and restarting MySQL should fix the problem.
See https://www.farbeyondcode.com/Solution-for-MariaDB-Field--xxx--doesn-t-have-a-default-value-5-2720.html
If editing that file doesn't fix the issue, see http://dev.mysql.com/doc/refman/5.6/en/option-files.html for other possible locations of config files.
Open phpmyadmin and goto 'More' Tab and select 'Variables' submenu.
Scroll down to find sql mode.
Edit sql mode and remove 'STRICT_TRANS_TABLES'
Save it.
In phpmyadmin, perform the following:
select ##GLOBAL.sql_mode
In my case, I get the following:
ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES ,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Copy this result and remove STRICT_TRANS_TABLES. Then perform the following:
set GLOBAL sql_mode='ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
Set a default value for Created_By (eg: empty VARCHAR) and the trigger will update the value anyways.
create table try (
name varchar(8),
CREATED_BY varchar(40) DEFAULT '' not null
);
When I had this same problem with mysql5.6.20 installed with Homebrew, I solved it by going into my.cnf
nano /usr/local/Cellar/mysql/5.6.20_1/my.cnf
Find the line that looks like so:
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
Comment above line out and restart mysql server
mysql.server restart
Error gone!
Run mysql console:
mysql -u your_username -p
, select database:
USE your_database;
and run (also from mysql console):
SET GLOBAL sql_mode='';
That will turn off strict mode and mysql won't complain any more.
To make things clear: your database definition says "this field must have default value defined", and by doing steps from above you say to MySql "neah, just ignore it". So if you just want to do some quick fix locally this solution is ok. But generally you should investigate in your database definition and check if field really needs default value and if so set it. And if default value is not needed this requirement should be removed to have clean situation.
As others said, this is caused by the STRICT_TRANS_TABLES SQL mode.
To check whether STRICT_TRANS_TABLES mode is enabled:
SHOW VARIABLES LIKE 'sql_mode';
To disable strict mode:
SET GLOBAL sql_mode='';
Before every insert action I added below line and solved my issue,
SET SQL_MODE = '';
I'm not sure if this is the best solution,
SET SQL_MODE = ''; INSERT INTO `mytable` ( `field1` , `field2`) VALUES ('value1', 'value2');
Modify your query and add "IGNORE" as:
INSERT IGNORE INTO `mytable` ( `field1` , `field2`) VALUES ('value1', 'value2');
Its work and tested Copy to Config File: /etc/mysql/my.cnf OR /bin/mysql/my.ini
[mysqld]
port = 3306
sql-mode=""
then restart MySQL
This appears to be caused by a long-standing (since 2004) bug (#6295) in MySQL, titled
Triggers are not processed for NOT NULL columns.
It was allegedly fixed in version 5.7.1 of MySQL (Changelog, last entry) in 2013, making MySQL behave as “per the SQL standard” (ibid).
For Windows WampServer users:
WAMP > MySQL > my.ini
search file for sql-mode=""
Uncomment it.
In Windows Server edit my.ini (for example program files\mysql\mysql server n.n\my.ini)
I would not simply set the sql-mode="", rather I suggest one removes STRICT_TRANS_TABLES from the line, leave everything as-was, and then restart MySQL from the services utility. Add a comment for future programmers who you are and what you did.
Most of these answers are a lot of work for the not-seasoned coder. Like mentioned the issues is with STRICT_TRANS_TABLES.
First verify STRICT_TRANS_TABLES is running.
$ mysql -u root -p -e "SHOW VARIABLES LIKE 'sql_mode';"
You can disable strict mode on your MySQL server by running the following command on your Linode's command line:
$ mysql -u root -p -e "SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION';"
Then, you can verify that the mode is set by running the following:
$ mysql -u root -p -e "SELECT ##GLOBAL.sql_mode;"
This answer was found here https://www.linode.com/community/questions/17070/how-can-i-disable-mysql-strict-mode
i set the fields to not null and problem solved, it updates when an information is commanded to store in it, no more showing msqli message that the field was empty cus you didnt insert value to it, well application of this solution can work on some projects depends on your project structure.
This is for SYNOLOGY device users:
How to set global variables (strict mode OFF) on SYNOLOGY device.
(checked on DSM 7.0.1-42218 - device model DS418)
Used PUTTY to connect:
login as root and
sudo su after... (to be admin total)
if not exist create my.cnf in:
MariaDB 5:
/var/packages/MariaDB/etc
MariaDB 10:
/var/packages/MariaDB10/etc
this should be in the file (at least for strict mode off)
# custom configs
[mysqld]
innodb_strict_mode = OFF
sql_mode = ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
restart mysqld daemon:
MariaDB 5:
/usr/syno/bin/synopkg restart MariaDB
MariaDB 10:
/usr/syno/bin/synopkg restart MariaDB10
check for strict mode enabled at these two global options - both should be not there or off (see config above)
log into mysql:
mysql -u root -p
enter password:
show variables like 'sql_mode';
show variables like '%STRICT%';
i solved problem changing my.ini file located in data folder. for mysql 5.6 my.ini file moved to data folder rather the bin or mysql installation folder.
I think in name column have null values in this case.
update try set name='abc' where created_by='def';
I am using Xampp 7.3.28-1 for Linux. It uses MariaDB 10.4.19. Its configuration file is:
/opt/lampp/etc/my.cnf
It does NOT contain an entry that defines sql_mode.
However the query "select ##GLOBAL.sql_mode;" does return a result and it contains the problematic STRICT_TRANS_TABLES. I guess it is by default now.
My solution was to explicitly define the mode by adding this line below [mysqld]:
sql_mode=NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
You can define the modes that you need or just leave it blank.
I found that once I removed what was a doubling up of a foreign key and primary key, when I could have just used the foreign key as the primary key alone in the table. All my code then worked and I was able to upload to db.

Magento 1.9 to 2 Migration : General error: 1419 You do not have the SUPER privilege and binary logging is enabled

I m migrating magento 1.9 to 2.x and when i try to migrate data using the migrate:data command it stops with the following error
[Zend_Db_Statement_Exception]
SQLSTATE[HY000]: General error: 1419 You do not have the SUPER
privilege and binary logging is enabled (you might want to use the
less safe log_bin _trust_function_creators variable), query was:
CREATE TRIGGER trg_catalog_compare_item_after_insert AFTER INSERT ON
catalog_compare_item FOR EACH ROW BEGIN
INSERT INTO m2_cl_catalog_compare_item (`catalog_compare_item_id`,
`operation`) VALUES (NEW.catalog_compare_item_id, 'INSERT')ON
DUPLICATE KEY UPDATE operation = 'INSERT';
END `
In my mysql server log_bin is set to off and i m using a super user. Can anyone help me to sort this out? Thanks!
To resolve this, the value of the log_bin_trust_function_creators parameter as 1.
For more information log_bin_trust_function_creators
one can execute below SQL:
mysql -u USERNAME -p
set global log_bin_trust_function_creators=1;
Possible reason: The latest gen of RDS MySQL has triggers disabled (while first gen apparently had it enabled default).

Docker MySQL does not popoulate database with data

I have following docker-compose.yml
version: '2'
services:
storage:
image: library/mysql:5.5
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=storage
ports:
- 3306:3306
volumes:
- ./mysql-initdb:/docker-entrypoint-initdb.d
- ./mysql-volume:/var/lib/mysql
Inside docker-entrypoint-initdb.d directory following .sql script:
BEGIN;
DROP DATABASE IF EXISTS `storage`;
CREATE DATABASE `storage`;
USE `storage`;
DROP TABLE IF EXISTS SETTINGS;
CREATE TABLE SETTINGS (
`NAME` VARCHAR(100) NOT NULL,
`VALUE` VARCHAR(100) NOT NULL,
PRIMARY KEY(`NAME`)
) ENGINE=MEMORY DEFAULT CHARSET=utf8;
INSERT INTO
`storage`.`SETTINGS` (`NAME`, `VALUE`)
VALUES
('AAAAA','BBBBB');
COMMIT;
When I executes docker-compose up I get information that .sql script is executed:
/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/1_storage_schema.sql
When I connect to that database from MySQL Workbench I see only empty tables without data. It looks like INSERT statement was not executed.
I tried also:
Naming columns with and without "`" character
Using and not BEGIN/COMMIT
In the volumes you are missing a /, the correct syntax will be:
volumes:
- ./mysql/docker-entrypoint-initdb.d/:/docker-entrypoint-initdb.d
What is happening is, the content inside the folder is not getting copied, instead a folder is made inside the docker-entrypoint-initdb.d. To ensure it is present in correct place, look inside the container by using docker exec.
I was having the same issue. Mysql wasn't populating the tables. Mysql was defined as a Docker volume and the import sql was bind mounted. These definitions were fine. I dug a little bit more and found that I had MYSQL_USER and MYSQL_PASSWORD set in my environment. I was also trying to run some sql in a file called 0users.sql inside the /docker-entrypoint-initdb.d directory. That file was attempting to RECREATE the user defined in MYSQL_USER environment variable. I removed the 2 environment variables. Then, I removed the Docker container and mysql volume. Then, tried again. Worked.
My assumption is that if the container runs into any kind of SQL error, the entire import appears to stop. Since my file was at the top of the alphabetical order, the import died on user creation and no tables were imported.

MySQL General Log Not Starting on 'Set Global'

I am trying to set up my MySQL general log so that it can be switched on and off by using
SET GLOBAL general_log = 'ON'
SET GLOBAL general_log = 'OFF'
I would like it off by default (i.e. on server startup) but then have the ability to toggle it as above, so that I don't have to keep restarting the server. When I attempt to switch general logging ON as above, MySQL generates the following error:
Table 'mysql.general_log' doesn't exist
This is true - I have purposely not created this table as I would like logging to occur to file - NOT to tables. This suggests to me that that MySQL is trying to log the general queries to table even though the relevant global variables are set as below:
log_output = FILE
general_log = OFF
general_log_file = /var/log/mysql-general.log
The relevant part of the my.cnf is as follows:
[mysqld]
general-log = OFF
general-log-file = /var/log/mysql-general.log
I am using MySQL version 5.1.58 on a Linux server.
Thanks in advance,
Andy
Since the table mysql.general_log does not exist, I assume you upgraded from a previous version of MySQL and need to run mysql_upgrade to create them.
Backup all of your databases using mysqldump and do a filesystem backup of /var/lib/mysql, then execute the following commands:
mysql_upgrade -p --force
followed by
service mysql restart
or
/etc/init.d/mysql restart
If the general_log table still does not exist after taking these steps, follow the steps in this post: MySql - I dropped general_log table to manually create it.

Does mySQL Replication: Master DB Name has to be the same as the Slave DB name?

I have set the Master DB Name as MDB & in the Slave server I set to replicate-do-db=SDB <-- this did not work? But when I set it up as the same DB name it works. Is there any solution out there to setup 1 master db with 2 different slaves but in the same server??
You need to specify the replicate-rewrite-db option:
--replicate-rewrite-db=from_name->to_name
Tells the slave to translate the default database (that is, the one
selected by USE) to to_name if it was from_name on the master. Only
statements involving tables are affected (not statements such as
CREATE DATABASE, DROP DATABASE, and ALTER DATABASE), and only if
from_name is the default database on the master. This does not work
for cross-database updates. To specify multiple rewrites, use this
option multiple times. The server uses the first one with a from_name
value that matches. The database name translation is done before the
--replicate-* rules are tested.
If you are only replicating certain databases, you will need to specify the replicate-do-db. Note that the argument to this is the name of the database after the rename operation applied by replicate-rewrite-db:
--replicate-do-db=db_name
MySQL Replication with different database names
Add the following to the logging and replication section of your MySQL configuration file (/etc/mysql/my.cnf), I inserted mine right above relay-log.
replicate-rewrite-db = db_1->db_2
Replace db_1 with the database's name being replicated from the remote master and db_2 with the destination database's name.
Restart the MySQL server (/etc/init.d/mysql restart)
Access the MySQL shell (mysql -h localhost -u root -p)
Check the Slave status (SHOW SLAVE STATUS\G)