Installing MySQL on Fedora Linux using MariaDB. Since MySQL was sold to Oracle. MariaDB is a fork and open source version of MySQL.

Install MySQL on Fedora using MariaDB

$ sudo dnf install mariadb mariadb-server mariadb-devel

Start MariaDB

Run this to start the process:

$ sudo systemctl start mariadb

Later if you try to connect to MariaDB and get this error:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket

This means that you didn’t start the process. Or you restarted the machine and the process didn’t start.

For reference:

  • Stop: sudo systemctl stop mariadb
  • Restart: sudo systemctl restart mariadb
  • Status: sudo systemctl status mariadb
  • Start at boot: sudo systemctl enable mariadb

This the output of checking status with sudo systemctl status mariadb:

mariadb.service - MariaDB 10.5 database server
Loaded: loaded (/usr/lib/systemd/system/mariadb.service; disabled; vendor preset: disabled)
Active: active (running) since Wed 2021-05-05 09:24:50 EDT; 9min ago
    Docs: man:mysqld(8)
        https://mariadb.com/kb/en/library/systemd/

Process: 1137071 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS)
Process: 1137094 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mariadb.service
Process: 1137139 ExecStartPost=/usr/libexec/mysql-check-upgrade
Main PID: 1137129 (mysqld)
    Status: "Taking your SQL requests now..."
    Tasks: 8 (limit: 9124)
Memory: 124.4M
    CPU: 343ms
CGroup: /system.slice/mariadb.service

Config MariaDB

$ sudo mysql_secure_installation

In order to log into MariaDB to secure it, we’ll need the current password for the root user. If you’ve just installed MariaDB, and haven’t set the root password yet, you should just press enter here.

Enter current password for root (enter for none):

Setting the root password or using the unix_socket ensures that nobody can log into the MariaDB root user without the proper authorisation. You already have your root account protected, so you can safely answer ‘n’.

Switch to unix_socket authentication [Y/n] n
... skipping.

You already have your root account protected, so you can safely answer ‘n’.

Change the root password? [Y/n] n
... skipping.

By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment.

Remove anonymous users? [Y/n] y
... Success!

Normally, root should only be allowed to connect from ‘localhost’. This ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y
... Success!

By default, MariaDB comes with a database named ‘test’ that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment.

Remove test database and access to it? [Y/n] y
Dropping test database...
... Success!
Removing privileges on test database...
... Success!

Reloading the privilege tables will ensure that all changes made so far will take effect immediately.

Reload privilege tables now? [Y/n] y
... Success!

Cleaning up…

All done! If you’ve completed all of the above steps, your MariaDB installation should now be secure.

Thanks for using MariaDB!

Import a database schema

Login with your database user root using sudo:

$ sudo mysql -uroot -p

Create a new database:

mysql> create database db1;

Create a user with the syntax create user [username] identified by [password]:

mysql> create user 'homer'@'localhost' identified by 'simpson';

Grant access:

mysql> grant all on db1.* to 'homer'@'localhost';

Exit:

mysql> exit

Import the schema

$ mysql -u homer -p db1 < schema.sql

Import the data if this is in SQL script:

$ mysql -u homer -p db1 < data.sql

Connect to the database:

$ mysql -u homer -p db1

Import a database schema if grant access is set on the schema script

I worked on a project where grant access was set on the schema.sql script.

schema.sql
CREATE USER IF NOT EXISTS homer@localhost IDENTIFIED BY `simpson`;
DROP DATABASE IF EXISTS `db1`;
SET default_storage_engine=InnoDB;
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;

CREATE DATABASE IF NOT EXISTS db1
    DEFAULT CHARACTER SET utf8mb4
    DEFAULT COLLATE utf8mb4_unicode_ci;
USE db1;

GRANT SELECT, INSERT, UPDATE, DELETE, FILE ON *.* TO 'homer'@'localhost';
GRANT ALL PRIVILEGES ON `homer`.* TO 'homer'@'localhost';
GRANT ALL PRIVILEGES ON `db1`.* TO 'homer'@'localhost';

This means that this didn’t work, because the user was not previously created or granted access:

$ mysql -u homer -p db1 < schema.sql

I got this error:

ERROR 1227 (42000) at line 2: Access denied; you need (at least one of) the
CREATE USER privilege(s) for this operation

Login with your database user root using sudo:

$ sudo mysql -uroot -p

Create a new database:

mysql> create database db1;

Import like this:

$ sudo mysql -uroot -p db1 < schema.sql

Since the schema.sql creates the user and grants them access. Then you can run other scripts like this:

$ mysql -u homer -p db1 < data.sql
$ mysql -u homer -p db1
Enter password: 

Output:

Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 55
Server version: 10.4.17-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [db1]>

Using the help command

The help command helps you with syntax. Use like this:

MariaDB [db1]> help contents

This specific command shows a menu of these options:

For more information, type 'help <item>', where <item> is one of the
following
categories:
Account Management
Administration
Compound Statements
Data Definition
Data Manipulation
Data Types
Functions
Functions and Modifiers for Use with GROUP BY
Geographic Features
Help Metadata
Language Structure
Optimization and Indexes
Plugins
Procedures
Sequences
Storage Engines
Table Maintenance
Transactions
User-Defined Functions
Utility

Here are a few help commands.

Run help functions:

> help Functions
You asked for help about help category: "Functions"
For more information, type 'help <item>', where <item> is one of the following
categories:
Bit Functions
Comparison Operators
Control Flow Functions

This doesn’t work help 'Language Structure':

> help 'Language Structure'
Nothing found
Please try to run 'help contents' for a list of all accessible topics

This works help 'Data Types':

> help 'Data Types'
You asked for help about help category: "Data Types"
For more information, type 'help <item>', where <item> is one of the following
topics:
AUTO_INCREMENT
BIGINT
BINARY
BIT
BLOB
...

Run help 'create user':

> help 'create user'
Name: 'CREATE USER'
Description:
Syntax
------
CREATE [OR REPLACE] USER [IF NOT EXISTS]
user_specification [,user_specification ...]
[REQUIRE {NONE | tls_option [[AND] tls_option ...] }]
...

Enable Automcomplete on SQL prompt

It starts to get annoying when you have to type a long table name. Isn’t there an autocomplete like the Linux prompt?

There are three options:

  • Type rehash in the SQL prompt: MariaDB> rehash
  • Type \# in the SQL prompt: MariaDB> \#
  • Start MySQL with this flag: --auto-rehash

You can also create a config file in your home directory called .my.cnf:

[mysql]
auto-rehash

Foreign key constraint is incorrectly formed

I created another schema with a foreign key specified with a circular reference:

CREATE TABLE EMPLOYEE(
    Fname varchar(15) NOT NULL,
    Minit char,
    Lname varchar(15) NOT NULL,
    Ssn char(9) NOT NULL,
    Bdate date,
    Address varchar(30),
    Sex char,
    Salary decimal(10,2),
    Super_ssn char(9),
    Dno int NOT NULL DEFAULT 1,
    PRIMARY KEY(Ssn)
    );

ALTER TABLE EMPLOYEE
    ADD CONSTRAINT fk_Employee_Super_ssn_Employee_Ssn FOREIGN
    KEY(Super_ssn) REFERENCES EMPLOYEE(Ssn) ON DELETE SET NULL ON UPDATE
    CASCADE,

However, when I imported the schema, I got this error:

ERROR 1005 (HY000) at line 76: Can't create table `company`.`EMPLOYEE`
(errno: 150 "Foreign key constraint is incorrectly formed")

This was fixed by adding this before the ALTER:

SET FOREIGN_KEY_CHECKS=OFF;

And this after the ALTER:

SET FOREIGN_KEY_CHECKS=ON;

Cannot truncate a table referenced in a foreign key constraint

I have a SQL script to import the dataset into the database tables. It deletes all the data with TRUNCATE such as:

TRUNCATE TABLE EMPLOYEE;
TRUNCATE TABLE DEPARTMENT;

However, when I tried running the script the output was an error:

Cannot truncate a table referenced in a foreign key constraint

The solution was similar as above, set on/off FOREIGN_KEY_CHECKS:

SET FOREIGN_KEY_CHECKS=OFF;

TRUNCATE TABLE EMPLOYEE;
TRUNCATE TABLE DEPARTMENT;

SET FOREIGN_KEY_CHECKS=ON;

MySQL basics

Show users in the database:

$ sudo mysql -uroot -p
MariaDB> show databases;

Database
--------
db1
information_schema
mysql
performance_schema

MariaDB> select user from mysql.user;

User
----
homer
mariadb.sys
mysql
root

Show tables in the mysql database:

MariaDB> use mysql;
MariaDB [mysql]> show tables;
show tables output

    MariaDB [mysql]> show tables;
    +---------------------------+
    | Tables_in_mysql           |
    +---------------------------+
    | column_stats              |
    | columns_priv              |
    | db                        |
    | event                     |
    | func                      |
    | general_log               |
    | global_priv               |
    | gtid_slave_pos            |
    | help_category             |
    | help_keyword              |
    | help_relation             |
    | help_topic                |
    | index_stats               |
    | innodb_index_stats        |
    | innodb_table_stats        |
    | plugin                    |
    | proc                      |
    | procs_priv                |
    | proxies_priv              |
    | roles_mapping             |
    | servers                   |
    | slow_log                  |
    | table_stats               |
    | tables_priv               |
    | time_zone                 |
    | time_zone_leap_second     |
    | time_zone_name            |
    | time_zone_transition      |
    | time_zone_transition_type |
    | transaction_registry      |
    | user                      |
    +---------------------------+
    

Describe the user table in the mysql database:

MariaDB [mysql]> desc user;
desc user, some of the output

    +------------------------+------------+------+
    | Field                  | Type       | Null |
    +------------------------+------------+------+
    | Host                   | char(60)   | NO   |
    | User                   | char(80)   | NO   |
    | Password               | longtext   | YES  |
    | Select_priv            | varchar(1) | YES  |
    | Insert_priv            | varchar(1) | YES  |
    | Update_priv            | varchar(1) | YES  |
    | Delete_priv            | varchar(1) | YES  |
    | Create_priv            | varchar(1) | YES  |
    | Drop_priv              | varchar(1) | YES  |
    | Reload_priv            | varchar(1) | YES  |
    | Shutdown_priv          | varchar(1) | YES  | 
    | Process_priv           | varchar(1) | YES  | 
    | File_priv              | varchar(1) | YES  | 
    | Grant_priv             | varchar(1) | YES  | 
    | References_priv        | varchar(1) | YES  | 
    | Index_priv             | varchar(1) | YES  | 
    | Alter_priv             | varchar(1) | YES  | 
    | Show_db_priv           | varchar(1) | YES  | 
    | Super_priv             | varchar(1) | YES  | 
    | Create_tmp_table_priv  | varchar(1) | YES  | 
    | Lock_tables_priv       | varchar(1) | YES  | 
    | Execute_priv           | varchar(1) | YES  | 
    | Repl_slave_priv        | varchar(1) | YES  | 
    | Repl_client_priv       | varchar(1) | YES  | 
    | Create_view_priv       | varchar(1) | YES  | 
    | Show_view_priv         | varchar(1) | YES  | 
    | Create_routine_priv    | varchar(1) | YES  | 
    | Alter_routine_priv     | varchar(1) | YES  | 
    | Create_user_priv       | varchar(1) | YES  | 
    | Event_priv             | varchar(1) | YES  | 
    | Trigger_priv           | varchar(1) | YES  | 
    | Create_tablespace_priv | varchar(1) | YES  | 
    | Delete_history_priv    | varchar(1) | YES  | 
    | ssl_type               | varchar(9) | YES  | 
    

Show grants for a user:

MariaDB [mysql]> show grants for 'homer'@'localhost';

+---------------------------
Grants for homer@localhost
+---------------------------
GRANT USAGE ON *.* TO `homer`@`localhost` IDENTIFIED BY PASSWORD '...
GRANT ALL PRIVILEGES ON `db1`.* TO 'homer'@'localhost';

Inserting NULL values

When the schema is described as this example:

CREATE TABLE Store(
    Store_Number varchar(50) NOT NULL,
    Team_Size int(3) NULL DEFAULT NULL,
    primary key (Store_Number)
);

And you insert a record when you don’t have a value. In this case you don’t know the value of Team_Size:

INSERT INTO Store(Store_Number,Team_Size) VALUES('Store1',);

You might get this error:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual
that corresponds to your MariaDB server version for the right syntax
to use near ')' at line 1

Since the schema for Team_Size is set to NULL DEFAULT NULL. Then insert the record using as value DEFAULT like this:

INSERT INTO Store(Store_Number,Team_Size) VALUES('Store1',DEFAULT);

Escaping strings with single quote

Given this schema;

CREATE TABLE Holiday(
`Date` date NOT NULL,
Holiday_Name varchar(100) NOT NULL,
primary key (`Date`,Holiday_Name)
);

Inserting this with backticks:

INSERT INTO Holiday(`Date`, Holiday_Name) VALUES('2011-01-01',`Veteran's Day`);

Results in this error:

ERROR 1054 (42S22): Unknown column 'Veteran's Day' in 'field list'

Don’t use backticks. Use single quotes and escape the single quote within the string with two single quotes:

INSERT INTO Holiday(`Date`, Holiday_Name) VALUES('2011-01-01','Veteran''s Day');

Sources: