Got error 4239 'Trigger with given name already exists' from NDBCLUSTER - mysql

We are running a MySQL Cluster Version:
mysql> SELECT VERSION();
+------------------------------+
| VERSION() |
+------------------------------+
| 5.6.15-ndb-7.3.4-cluster-gpl |
+------------------------------+
Trying to create a table
CREATE TABLE xy (
xa VARCHAR(36) NOT NULL DEFAULT '',
xb VARCHAR(255) NOT NULL,
xc TIMESTAMP NOT NULL,
xd VARCHAR(36) DEFAULT NULL,
xe VARCHAR(36) DEFAULT NULL,
xf VARCHAR(255) DEFAULT NULL,
xg VARCHAR(255) DEFAULT NULL,
xh TEXT,
xi BIGINT(20) DEFAULT NULL,
xj VARCHAR(255) DEFAULT NULL,
xk VARCHAR(255) DEFAULT NULL,
xl VARCHAR(255) DEFAULT NULL,
xz VARCHAR(255) DEFAULT NULL,
xy VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (xa)
) engine=ndb;
brings me (using the direct input over command line):
ERROR 1296 (HY000): Got error 4239 'Trigger with given name already exists' from NDBCLUSTER
and via file:
ERROR 1296 (HY000) at line 8: Got error 4239 'Trigger with given name already exists' from NDBCLUSTER
But there are no mysql triggers:
mysql> SHOW triggers;
Empty set (0.00 sec)
and no tables:
mysql> show tables;
Empty set (0.01 sec)
Anyone got an idea?

Ok - We got it!
The MaxNoOfTriggers in config.ini has been reached.
From the Official documentation -> MaxNoOfTriggers:
Internal update, insert, and delete triggers are allocated for each unique hash index. (This means that three triggers are created for each unique hash index.) However, an ordered index requires only a single trigger object. Backups also use three trigger objects for each normal table in the cluster.
Replication between clusters also makes use of internal triggers.
This parameter sets the maximum number of trigger objects in the cluster.
The default value is 768.

Related

Select query on MYSQL table taking long time and getting timed out

I have a mysql table with 2 million rows, when I'm running any select query on the table it's taking long time to execute and ultimately it does not return any result.
I have tried running select query from both Mysql Workbench and terminal, it's the same issue happening.
Below is the table:
`object_master`
`key` varchar(300) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`bucket` varchar(255) DEFAULT NULL,
`object_name` varchar(300) DEFAULT NULL,
`object_type` varchar(50) DEFAULT NULL,
`last_modified_date` datetime DEFAULT NULL,
`last_accessed_date` datetime DEFAULT NULL,
`is_deleted` tinyint(1) DEFAULT '0',
`p_object` varchar(300) DEFAULT NULL,
`record_insert_time` datetime DEFAULT CURRENT_TIMESTAMP,
`record_update_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`key`)
ENGINE=InnoDB DEFAULT CHARSET=latin1
And below is the select query i'm running :
select `key` from object_master;
even with a limit 1 is also taking long time and not returning a result, its getting timed out :
select `key` from object_master limit 1;
Could anyone tell me what can be the real reason here?
Also I would like to mention: before I was running these select queries, there was an alter table statement executed on this table which got timed out after 10 minutes and table remained un-altered.
Following is the alter statement:
alter table object_master
modify column object_name varchar(1096) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL;
Note: Using MYSQL version 5.7.24 and Mysql running on Linux Docker container.
So I got this resolved:
There was Java batch program which was executing a query on the same table for long time and was holding a lock on the table. I found this through "processlist" table of information_schema.
Had to kill the long running query through terminal:
mysql> kill <processlist_id> ;
Then it released the lock on that table and all got resolved.
Got help from below SO answers:
Unlocking tables if thread is lost
How do I find which transaction is causing a "Waiting for table metadata lock" state?

mysql can not insert because no default value?

I have two tables with exactly the same schema. I can insert into one table but not another. The one that fails complains about no default value. Here's my create statement for the table
CREATE TABLE `t_product` (
`product_id` varchar(10) NOT NULL,
`prod_name` varchar(150) DEFAULT NULL,
`price` decimal(6,2) NOT NULL,
`prod_date` date NOT NULL,
`prod_meta` varchar(250) DEFAULT NULL,
`prod_key` varchar(250) DEFAULT NULL,
`prod_desc` varchar(150) DEFAULT NULL,
`prod_code` varchar(12) DEFAULT NULL,
`prod_price` decimal(6,2) NOT NULL,
`prod_on_promo` tinyint(1) unsigned NOT NULL,
`prod_promo_sdate` date DEFAULT NULL,
`prod_promo_edate` date DEFAULT NULL,
`prod_promo_price` decimal(6,2) NOT NULL,
`prod_discountable` tinyint(1) unsigned NOT NULL,
`prod_on_hold` tinyint(1) unsigned NOT NULL,
`prod_note` varchar(150) DEFAULT NULL,
`prod_alter` varchar(150) DEFAULT NULL,
`prod_extdesc` text,
`prod_img` varchar(5) NOT NULL,
`prod_min_qty` smallint(6) unsigned NOT NULL,
`prod_recent` tinyint(1) unsigned NOT NULL,
`prod_name_url` varchar(150) NOT NULL,
`upc_code` varchar(50) DEFAULT NULL,
PRIMARY KEY (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
When I run this statement in database1, it successfully inserts:
insert into t_product (product_id) values ('jlaihello');
When I run this exact statement in database2, I get the error:
ERROR 1364 (HY000): Field 'price' doesn't have a default value
Why is this error happening only in database2? As far as I can tell, the difference between database1 and database2 are:
database1 uses mysql Ver 14.14 Distrib 5.5.53, for debian-linux-gnu (i686) using readline 6.3
and
database2 uses mysql Ver 14.14 Distrib 5.7.16, for Linux (x86_64) using EditLine wrapper
How do I make database2 behave like database1?
EDIT
There are hundreds of tables affected by this. Basically we're moving a database over to a new server. And I did a mysqldump from db1, and imported into db2. t_product is just ONE of the tables affected by this. I'd like to avoid manually modifying the schema for the hundreds of tables. I prefer a "simple switch" that will make db2 behave like db1.
ERROR 1364 (HY000): Field 'price' doesn't have a default value
price decimal(6,2) NOT NULL,
Set price to null or assign a default value
EDIT:
This is caused by the STRICT_TRANS_TABLES SQL mode.
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.
OR
You can run an SQL query within your database management tool, such as phpMyAdmin:
-- verify that the mode was previously set:
SELECT ##GLOBAL.sql_mode;
-- update mode:
SET ##GLOBAL.sql_mode= 'YOUR_VALUE';
OR
Find the line that looks like so in the mysql conf file:
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
Comment above line out and restart mysql server
Most probably, the default for column price is missing in the second database. To check this you should output your table structure:
describe database2.t_product;
OR
show create table database2.t_product;
and check if the default is defined.
You can alter your table and add the missing default constraint like this:
ALTER TABLE database2.t_product MODIFY COLUMN decimal(6,2) NOT NULL DEFAULT 0
EDIT
Based on comments and specification (data type default values), I think there is a difference in sql_mode of the MySQL:
For data entry into a NOT NULL column that has no explicit DEFAULT
clause, if an INSERT or REPLACE statement includes no value for the
column, or an UPDATE statement sets the column to NULL, MySQL handles
the column according to the SQL mode in effect at the time:
If strict SQL mode is enabled, an error occurs for transactional
tables and the statement is rolled back. For nontransactional tables,
an error occurs, but if this happens for the second or subsequent row
of a multiple-row statement, the preceding rows will have been
inserted.
If strict mode is not enabled, MySQL sets the column to the implicit
default value for the column data type.
So, if strict mode is not enabled for the first database, INSERT/UPDATE is allowed and storing the default value of that type (a 0 decimal)

mySQL create table script with output

What I am currently looking to do is write a script where I use CREATE TABLE IF NOT EXISTS statements to create missing tables. How exactly could I go about adding in some sort of output to the user who is using this script? It is essentially a long line of create table statements and I would like it to print out something like "this_table was added" at the end of the script. I want to output something for the tables that are not found, and are created.
CREATE TABLE IF NOT EXISTS`user_group` (
`key` varchar(255) NOT NULL,
`version` int(11) NOT NULL,
`display_order` int(11) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
`color` varchar(10) DEFAULT NULL,
PRIMARY KEY (`key`)
) ENGINE=genericDB DEFAULT CHARSET=latin1;
Define a delimiter to run two queries together
mysql> delimiter //
mysql> create table Y(id int primary key)//select "Y Created";//
Query OK, 0 rows affected (0.13 sec)
+-----------+
| Y Created |
+-----------+
| Y Created |
+-----------+
1 row in set (0.00 sec)

ERROR 1146 (42S02): Table 'mysql.general_log' doesn't exist

After mysql upgrade I'm getting this error on my Centos box when I tried to enable general_log. Any idea?
SET GLOBAL general_log = 'ON';
ERROR 1146 (42S02) : Table 'mysql.general_log' doesn't exist
I have created that missing table and worked for me.
Login to mysql console
use mysql;
CREATE TABLE general_log(
event_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
user_host mediumtext NOT NULL,
thread_id int(11) NOT NULL,
server_id int(10) unsigned NOT NULL,
command_type varchar(64) NOT NULL,
argument mediumtext NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'
When you find yourself in this situation then you problem have done a MySQL upgrade and incorrectly carried over the datadir (e.g. /usr/local/var/mysql) to the new installation.
So the accepted solution above will solve your immediate problem but it also indicates that you might have other problems with your MySQL install as well.
just an Addition to Harikrishnan's answer!
I had to alter the fields type to work from me as MYSQL could not write to table so:
if general_log is enabled, turn it off SET GLOBAL general_log= 0;
Create table
USE mysql;
CREATE TABLE mysql.general_log(
event_time TIMESTAMP(6) NOT NULL DEFAULTCURRENT_TIMESTAMP(6) ON UPDATECURRENT_TIMESTAMP(6),
user_host MEDIUMTEXT NOT NULL,
thread_id BIGINT(21)UNSIGNED NOT NULL,
server_id INT(10) UNSIGNED NOT NULL,
command_type VARCHAR(64) NOT NULL,
argument MEDIUMBLOB NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log';
reenable logging SET GLOBAL general_log= 1;
view log SELECT * FROM mysql.general_log;

Creating tables in MySQL

I created a table license_serial in my "database_name". But when I tried creating a second table named license, it says that it already exists.
Why is that ? My database contains only a license_serial.frm and a db.opt.
mysql> SHOW TABLES;
+---------------------+
| Tables_in_mobilemp3 |
+---------------------+
| license_serial |
+---------------------+
1 row in set (0.00 sec)
mysql> select * from license;
ERROR 1146 (42S02): Table 'mobilemp3.license' doesn't exist
Creating the second table:
CREATE TABLE `license` (
`id` int(10) unsigned NOT NULL auto_increment,
`serial_id` int(10) unsigned NOT NULL,
`uid` bigint(20) unsigned NOT NULL,
`active` tinyint(1) NOT NULL,
`first_seen` timestamp NOT NULL default CURRENT_TIMESTAMP,
`last_seen` timestamp NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `serial_uid` (`serial_id`,`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
gives the following error message:
ERROR 1050 (42S01): Table 'mobilemp3.license' already exists
EDIT:
And the solution is this(in this order):
drop database databasename;
create database databasename;
use databasename;
The only thing I can think of, is that the table was created e.g. by root and the user you are using does not have access to that table. In that case you cannot select from it (not sure if it would be filtered out in the show tables command though)
Log in as root to that database and check if that table exists.