Archive for the ‘ How tos ’ Category

What type of storage engine a MySQL table uses?

MySQL supports several storage engines such as InnoDB, MyISAM, BLACKHOLE, CSV. Depending on your use case, you might configure your MySQL table to use certain storage engine. To see the list of storage engines MySQL supports, simply run “SHOW ENGINES\G” under a mysql prompt.

To find out the particular storage engine used by a table, run the ‘show table status’ command for the named table as below. The first example is the mysql user table, which uses InnoDB –

mysql> use mysql;

mysql> show table status like 'user' \G
*************************** 1. row ***************************
Name: user
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 1
Avg_row_length: 16384
Data_length: 16384
Max_data_length: 0
Index_length: 49152
Data_free: 10485760
Auto_increment: 2
Create_time: 2013-08-26 22:52:09
Update_time: NULL
Check_time: NULL
Collation: binary
Checksum: NULL
1 row in set (0.00 sec)

A sample table which uses MyISAM storage engine –

mysql> show table status like 'servers' \G
*************************** 1. row ***************************
Name: servers
Engine: MyISAM
Version: 10
Row_format: Fixed
Rows: 0
Avg_row_length: 0
Data_length: 0
Max_data_length: 433752939111120895
Index_length: 1024
Data_free: 0
Auto_increment: NULL
Create_time: 2013-08-24 01:42:15
Update_time: 2013-08-24 01:42:15
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Comment: MySQL Foreign Servers table
1 row in set (0.00 sec)

A table for logging slow queries is stored in a CSV storage engine –

mysql> show table status like 'slow_log' \G
*************************** 1. row ***************************
Name: slow_log
Engine: CSV
Version: 10
Row_format: Dynamic
Rows: 2
Avg_row_length: 0
Data_length: 0
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: NULL
Create_time: NULL
Update_time: NULL
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Comment: Slow log
1 row in set (0.00 sec)


Features of some of the storage engines –

  • InnoDB: is a transaction-safe (ACID compliant) storage engine for MySQL that has commit, rollback, and crash-recovery capabilities to protect user data. 
  • MyISAM: These tables have a small footprint. Table-level locking limits the performance in read/write workloads, so it is often used in read-only or read-mostly workloads in Web and data warehousing configurations.
  • Memory: Stores all data in RAM, for fast access in environments that require quick lookups of non-critical data.
  • CSV: Its tables are really text files with comma-separated values. CSV tables let you import or dump data in CSV format, to exchange data with scripts and applications that read and write that same format.
  • Archive: These compact, unindexed tables are intended for storing and retrieving large amounts of seldom-referenced historical, archived, or security audit information.
  • Blackhole: The Blackhole storage engine accepts but does not store data, similar to the Unix /dev/null device. Queries always return an empty set.


References –

nf_conntrack: table full, dropping packet

I actually saw this error in a Docker host, and Docker uses iptables and allof Docker’s iptables rules are added to the DOCKER chain. In this case though, it wasn’t the Docker iptables rules that were a problem, it is just that limits were reached in the connection tracking of the netfilter module. You might see this error in /var/log/messages or /var/log/kern

The full error message looked like this –

May 29 09:10:37 docker kernel: [74350.150400] nf_conntrack: table full, dropping packet
May 29 09:10:37 docker kernel: [74350.155361] nf_conntrack: table full, dropping packet
May 29 09:10:37 docker kernel: [74350.160282] nf_conntrack: table full, dropping packet
May 29 09:10:37 docker kernel: [74350.181547] nf_conntrack: table full, dropping packet
May 29 09:10:37 docker kernel: [74350.184807] nf_conntrack: table full, dropping packet
May 29 09:10:37 docker kernel: [74350.184913] nf_conntrack: table full, dropping packet

Resolution – increase maximum number of connections being tracked and/or reduce tracking timeouts. Look for these run time kernel parameters –

[root@kauai /]# sysctl net.ipv4.netfilter.ip_conntrack_tcp_timeout_established
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 27000
[root@kauai /]# sysctl net.netfilter.nf_conntrack_generic_timeout
net.netfilter.nf_conntrack_generic_timeout = 60
[root@kauai /]# sysctl net.ipv4.netfilter.ip_conntrack_max
net.ipv4.netfilter.ip_conntrack_max = 64268

These are the settings which resolved my issue, simply doubled the values –

sysctl -w net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=54000
sysctl -w net.netfilter.nf_conntrack_generic_timeout=120
sysctl -w net.ipv4.netfilter.ip_conntrack_max=128536

To make this permanent, add the lines above to the /etc/sysctl.conf file.


References –

IP subnet calculator

Linux – IP subnet calculation with ipcalc

ipcalc is a program to perform simple manipulation of IP addresses and is useful for calculating various network masks given an IP address. Some of the uses of ipcalc are –

  • Validate IP address
  • Display calculated broadcast address
  • Show hostname determined via DNS
  • Display default mask for IP
  • Display network address or prefix

Before using ipcalc, make sure you have the binary installed in your Operating system, if not install it by following below instructions –

1. Installation instructions for various Operating Systems

a. Fedora/Red Hat/CentOS

yum install initscripts

b. Debian/Ubuntu

apt-get install ipcalc

c. MacOS

brew install ipcalc

Install ipcalc on Mac OSX

d. Windows


2. How to use ipcalc

Note below examples were tested in CentOS 6.8, it might not work for other distros or Operating systems. Check the ipcalc documentation for your OS.

a. Check if IP address is valid for IPv4 or IPv6 ( it defaults to IPv4)

[daniel@kauai ~]$ ipcalc -c
[daniel@kauai ~]$ ipcalc -c
[daniel@kauai ~]$ ipcalc -c
ipcalc: bad IPv4 address:

It will exit with a non-zero status code if the IP address is not valid, with zero if valid. For scripting, use ‘-s’ option for silent, that way it doesn’t display error messages.

[daniel@kauai ~]$ ipcalc -s -c
[daniel@kauai ~]$ echo $?

[daniel@kauai ~]$ ipcalc -s -c
[daniel@kauai ~]$ echo $?

b. Show boradcast address 

[daniel@kauai ~]$ ipcalc -b
[daniel@kauai ~]$ ipcalc -b
[daniel@kauai ~]$ ipcalc -b

c. Reverse dns

[daniel@kauai ~]$ ipcalc -h

$ ipcalc -h

d.  Display default netmask for IP (class A, B, or C)

[daniel@kauai ~]$ ipcalc -m
[daniel@kauai ~]$ ipcalc -m
[daniel@kauai ~]$ ipcalc -m


e. Show network address

[daniel@kauai ~]$ ipcalc -n
[daniel@kauai ~]$ ipcalc -n
[daniel@kauai ~]$ ipcalc -n


Split a subnet – this feature might not be supported in all ipcalc versions, check for your OS.

This is the best feature of ipcalc in my opinions, you dont’ have to do the subnet and bits calculation by hand. This feature was available in my Ubuntu 16 VM but not RedHat.

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.3 LTS
Release: 16.04
Codename: xenial

$ ipcalc -v

For instance to split a /20 subnet into two subnets of size 1024 each –

ipcalc --s 1024 1024
Address: 00001010.00001010.0000 0000.00000000
Netmask: = 20 11111111.11111111.1111 0000.00000000
Wildcard: 00000000.00000000.0000 1111.11111111
Network: 00001010.00001010.0000 0000.00000000
HostMin: 00001010.00001010.0000 0000.00000001
HostMax: 00001010.00001010.0000 1111.11111110
Broadcast: 00001010.00001010.0000 1111.11111111
Hosts/Net: 4094 Class A, Private Internet

1. Requested size: 1024 hosts
Netmask: = 21 11111111.11111111.11111 000.00000000
Network: 00001010.00001010.00000 000.00000000
HostMin: 00001010.00001010.00000 000.00000001
HostMax: 00001010.00001010.00000 111.11111110
Broadcast: 00001010.00001010.00000 111.11111111
Hosts/Net: 2046 Class A, Private Internet

2. Requested size: 1024 hosts
Netmask: = 21 11111111.11111111.11111 000.00000000
Network: 00001010.00001010.00001 000.00000000
HostMin: 00001010.00001010.00001 000.00000001
HostMax: 00001010.00001010.00001 111.11111110
Broadcast: 00001010.00001010.00001 111.11111111
Hosts/Net: 2046 Class A, Private Internet

Needed size: 4096 addresses.
Used network:


Let us split it into 3 subnets of sizes 512, 512 and 1024



Useful links –


Python modify user-agent

How to generate user-agent header for web requests in Python

In previous post, we saw how to modify user-agent header in wget, curl and httpie programs. In this post, I will show you how to modify user-agent header in Python’s popular requests module. There are several reasons for modify user agent, one of which is to trigger a different response from a website. Many website offer different content based on user-agent header. You can find user-agent header details here.

In Python, one of the most popular libraries to query web servers is the requests module. The requests module allows you to pass header information using the headers option –

1. Simplest use case, without a header

import requests

And this is how it is logged on the web server side, Apache in this case – [20/May/2018:01:08:37 -0400] "GET /status HTTP/1.1" 200 359 "-" "python-requests/2.18.4" 1798

The user-agent is simply showing as “python-requests/2.18.4”, and some website might even block this to prevent web crawlers. So the next step is to modify this.


2. Modify user-agent header

headers = {'User-Agent': 'Mozilla/5.0 (Android 5.1; Tablet; rv:50.0) Gecko/50.0 Firefox/50.0'}
requests.get('', headers=headers)

And this is what the access log entry looks like on the web server side –  [20/May/2018:01:11:29 -0400] "GET /status HTTP/1.1" 200 359 "-" "Mozilla/5.0 (Android 5.1; Tablet; rv:50.0) Gecko/50.0 Firefox/50.0" 1289

As you can see above, the user-agent entry has several identifiers which is not easy to remember. The best way would be to programatically generate valid user-agents for different platforms.


3. Generate valid user-agents

The user_agent module is used for generating random and yet valid web user agents. You can install it with ‘pip install user_agent’.

This module generate user-agent strings for differnt devices types such as desktop, smartphone and table, as well as OS types (Windows, Linux, Mac, Android …). Let us try it in a virtual environment –

virtualenv /tmp/venv
source /tmp/venv/bin/activate
pip install user_agent

Now run Python in an interactive mode –

import requests
from user_agent import generate_user_agent 

In [8]: generate_user_agent()
Out[8]: 'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2803.5 Safari/537.36'

In [9]: generate_user_agent()
Out[9]: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0'

In [11]: generate_user_agent(os='linux')
Out[11]: 'Mozilla/5.0 (X11; Ubuntu; Linux i686 on x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2942.3 Safari/537.36'

In [13]: generate_user_agent(device_type='tablet')
Out[13]: 'Mozilla/5.0 (Linux; Android 4.4; HTC Desire 616 dual sim Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2938.21 Safari/537.36'

In [14]: generate_user_agent(device_type='desktop', os='win')
Out[14]: 'Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0'

In [20]: generate_user_agent(navigator='chrome', os='linux', device_type='desktop')
Out[20]: 'Mozilla/5.0 (X11; Ubuntu; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2894.26 Safari/537.36'

This allows us to generate from random to specific valid user-agent header information. We can then pass this randomly generated user-agent text to the requests module header option, and we will view our web server logs to validate –

from user_agent import generate_user_agent
import requests
requests.get('', headers={'User-Agent': generate_user_agent(navigator='firefox', os='linux')})

Log entry – – – [20/May/2018:01:28:24 -0400] “GET /status HTTP/1.1” 200 359 “-” “Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0” 1486


References –

Configure IP Aliases in Red Hat / CentOS

IP aliasing is a term for assigning multiple IP addresses to a single network interface. It is quite useful in a shared web hosting for instance, particularly if the domains have SSL certificates. You can setup each domain to resolve to different IP address, even if they are all sharing the same network interface.

You have to be root to perform this tasks.

1. Disable Network Manager

# service NetworkManager stop

# chkconfig NetworkManager off

2. Add IP alias from cli

# ip addr addr add dev eth0 label eth0:1

# ip addr show eth0

3. Persistently add lias

Create the file /etc/sysconfig/network-scripts/ifcfg-eth0:1

# cat /etc/sysconfig/network-scripts/ifcfg-eth0:1

4. Restart network service

# service network restart
# ip addr show eth0


How to install  Ubuntu 18.04 LTS (Bionic Beaver)

Installation steps for Ubuntu 18.04, code named Bionic Beaver. This steps are for the desktop version.

One notable change is Unity is no longer the default desktop environment for Ubuntu anymore. It will feature the latest GNOME (i.e., version 3.28).  The Linux kernel version on Ubuntu 18.04 is 4.15.

1. Download iso  from the site
Desktop image (AMD64) –
Server image (AMD64) –

2. Select disc image file (iso) during installation

In my case, I am using VMware player, I select disc image file (iso) during the creation of the VM.


3. Personalize Linux

In this step, it will ask you for your full name, username, password and to confirm your password.

4. For VMware player, make sure to  customize hardware, select the memory size to allocate (2GB in my case, minimum requirement is 1G), disk size, number of vCPUs etc.

Right after finishing the hardware customization and click start, it will immediately start creating the file system and installing software.

Once completed, the system will reboot.

5. Login screen – enter the username and password you submitted when installing the iso.

6. What is new screen

7. Start testing some of the applications

a. The command terminal


b. Firefox browser


By default Ubuntu 18.04 comes with Gnome 3, you can install KDE plasma and use that as your windows manager. Here are the steps –

1. Run the following commands from the terminal to install kde plasma

sudo apt-get update
apt-get install tasksel -y
sudo tasksel install kubuntu-desktop

2. After rebooting, select Plasma


Links – 

Release notes – Bionic Beaver release notes

What is new –