Tag: mysql

How to setup a Replication User

How to setup a Replication User


A replication user is necessary to set up the relationship Primary/Replica. This is a short step but it needs a bit more of attention.

From the MySQL 5.7 documentation (highlights are my own):

Although you do not have to create an account specifically for replication, you should be aware that the replication user name and password are stored in plain text in the master info repository file or table (see Section, “Slave Status Logs”). Therefore, you may want to create a separate account that has privileges only for the replication process, to minimize the possibility of compromise to other accounts.

The following command specifically will allow replication from all databases and tables connecting from all hosts. For security reasons you may want to limit access to replication only to the IP address of the server doing the replication.

Log into the MySQL console using a user with GRANT privileges in the primary server and execute the following:

CREATE USER 'replication'@'%' IDENTIFIED BY 'mysupersecretpassword'
GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%';

My advice is instead of using the % wildcard, set up the IP address of your replica.

This user will be added to the primary ’s MASTER_USER option, and in theory could be any user as long it also has REPLICATION SLAVE privileges. After that, the replica will connect to the primary and perform some kind of handshake with those credentials and if they match, theprimary will allow replication to occur.

See something wrong in this tutorial? Please don’t hesitate to message me through the comments or the contact page.

How to reset your `root` password on your MySQL server

How to reset your `root` password on your MySQL server

You don’t need this tutorial if you have access to the root user or another one with SUPER and GRANT privileges.

The following instructions works for MySQL 5.7. You will need to stop the MySQL server and start it with mysqld_safe with the option skip-grant-tables:

sudo service mysql stop
sudo mysqld_safe --skip-grant-tables &
mysql -u root mysql

If you get an error on start, chances are there is no folder created for the mysqld_safe executable to run, on my tests I was able to solve by doing:

sudo mkdir /var/run/mysqld
sudo chown -R mysql:mysql /var/run/mysqld

And then trying to start the mysqld_safe process again.

After this, the MySQL console will pop up, and you need to set up a new password for root. The second line is necessary due to a MySQL bug #79027:

UPDATE mysql.user SET authentication_string=PASSWORD('mypassword') WHERE User='root';
UPDATE mysql.user SET plugin="mysql_native_password" WHERE User='root';

Once finished, kill all MySQL processes and start the service again:

ps aux | grep mysql
sudo kill -9 [pid]
sudo service mysql start

Done, you have reset the root password! Make sure to keep it safe this time around!

See something wrong in this tutorial? Please don’t hesitate to message me through the comments or the contact page.

A small dive into the MySQL 8.0 X-DevAPI

A small dive into the MySQL 8.0 X-DevAPI


What is the X-DevApi? From insidemysql.com there is a definition of the X-DevAPI and its features in the following paragraphs:

The X DevAPI is the common client-side API used by all connectors to abstract the details of the X Protocol. It specifies the common set of CRUD-style functions/methods used by all the official connectors to work with both document store collections and relational tables, a common expression language to establish query properties such as criteria, projections, aliases, and a standard set of additional database management features for handling things like transactions, indexes, etc.

The fact that most of these features share the same format and API between connectors, makes the X DevAPI a perfect fit for modern polyglot development environments such as microservices, and the fact that they are based on a well-documented format allows advanced users to extend client-side implementations and build new middleware components or extensions tailor-made for their use case.

With MySQL 8.0, the X-DevAPI can be used either with the MySQL Shell, or with the MySQL Connectors that supports the X-Protocol. For this blogpost I will be showing you code using the Node.js driver as interface with it.

As of the moment of writing of this post, the latest version for the driver (available on npm) is the 8.0.11.

Hands-on, the relational way

You can use the X-DevAPI to use it in a more “relational” way, consider a table teams from the worldcup schema:



Field Type Null Key Default Extra
id int(11) NO PRI NULL auto_increment
name varchar(255) NO NULL
players json YES NULL

Notice that the field players is a JSON and it can be NULL.

const mysqlx = require('@mysql/xdevapi');
const options = require('./config')
.then((session) => {
const db = session.getSchema("worldcup");
const tableTeams = db.getTable("teams");
return tableTeams;
.then((t) => {
t.select(['id', 'name', 'players'])
.where('name = :name')
.bind('name', 'Brazil')
.catch(err => {
view raw xdevapi1.js hosted with ❤ by GitHub

Returns on a browser (data clipped):

"Brazil ",
"players": [{
"id": 70,
"dob": "05.03.1993",
"club": "FC Shakhtar Donetsk (UKR)",
"name": "FRED",
"height": 169,
"weight": 64,
"position": "MF",
"shirt_name": "FRED",
"shirt_number": 18
"id": 71,
"dob": "13.01.1988",
"club": "FC Shakhtar Donetsk (UKR)",
"name": "TAISON",
"height": 172,
"weight": 64,
"position": "FW",
"shirt_name": "TAISON",
"shirt_number": 21
view raw xdevapi2.js hosted with ❤ by GitHub

Or on your terminal:

Extra padding on strings

This looks handy, specially if you are working as a document store (which I will talk in a bit), however there are some issues with JSON and VARCHAR fields for now:

  1. VARCHAR fields are getting padded. Take a look at the third line, where it is “Brazil” actually has trailing spaces. Notice on the terminal is how far off the closing quote is.
  2. JSON does work, but a bit in a limited way, in this case, it is only bringing the result set because the column is set to be possibly NULL, on the other hand if you execute the following you will have trouble:
Error on NOT NULL for JSON columns

See how the error is in a string parser that tries to concatenate whatever to it. On my tests usually is empty space, I had zeroes padded on the right too (yes zero on a string), problem 1 looks like is causing problem 2.

They are aware of it, and apparently it will be fixed on a future release.

Hands-on, the document store way

MySQL 8.0 has been marketed extensively as an alternative for NoSQL, although you can actually use JSON with it, there are some caveats to the feature.

I restructured data to be inside a collection instead of a table.

To query it now, you do the following:

const mysqlx = require('@mysql/xdevapi');
const options = require('./config')
.then((session) => {
const db = session.getSchema("worldcup");
let teamsCollection = db.getCollection("teams_2018");
return teamsCollection.find("name = :country1 OR name = :country2")
.bind("country1", "Brazil")
.bind("country2", "England")
.catch(err => {
view raw xdevapi3.js hosted with ❤ by GitHub

Something feels wrong to me with this approach of having to write strings instead of dealing with JavaScript objects inside the .find() method, using the “literal” word for OR and AND. I think there is room for improvement here. At this point I am sorry to say this looks more like as an hasty ORM put together than a real document store interface.

By the way, problem 1 and problem 2 don’t happen here:

Result set for a query

Should I use it now?

I would recommend to wait a bit more. The current version is the first General Availability version, which means next one will have bug fixes and more stability added to it. This definitely is a nifty way for those using Node.js to be able to manipulate data inside MySQL more “natively”, with that in mind, I still feel that I am actually writing SQL to be able to use it the “document store” way.


You can actually use the X-DevAPI on Google Cloud Functions.

You need to add the @mysql/xdevapi to package.json and put the code above inside a “wrapper” that looks like this:

* Responds to any HTTP request that can provide a "message" field in the body.
* @param {!Object} req Cloud Function request context.
* @param {!Object} res Cloud Function response context.
const options = {
host: "your ip address",
port: 33060,
password: "your password",
user: "your username"
const mysqlx = require('@mysql/xdevapi');
exports.getTeam = (req, res) => {
if (req.query.name === undefined) {
res.status(400).send('No name defined!');
} else {
const name = req.query.name;
/** your code goes here **/
.then((session) => {
const db = session.getSchema("worldcup");
let teamsCollection = db.getCollection("teams_2018");
return teamsCollection.find("name = :country")
.bind("country", req.query.name)
.execute(row => {
.catch(err => {
view raw xdevapi4.js hosted with ❤ by GitHub

Keep in mind that .execute() doesn’t return a promise, but rather receives a callback function to do your data processing of each individual row. This could be a bit annoying for you.

Image header of the post belongs to Pexel. And yes, I know the code shown is not SQL or JavaScript 🙂