GUEST OS: Centos 6.7 final
HOST OS: Windows 7
Virtualbox version: 5.0.4
1 | yum install gcc kernel-devel kernel-headers dkms make bzip2 perl |
iptables –line -vnL
iptables -I INPUT 5 -p tcp –dport 80 -m state –state NEW,ESTABLISHED -j ACCEPT
service iptables save
If you’re running your database on an SSD instead of a spinning disk, you might want to optimize postgres table space cost:
1 2 3 4 5 6 7 8 9 10 | -- Change the tablespace cost ALTER TABLESPACE pg_default SET ( seq_page_cost = 20, random_page_cost = 1 ); -- Verifiy the change SELECT * FROM pg_tablespace; -- Undo the tablespace cost ALTER TABLESPACE pg_default RESET ( seq_page_cost, random_page_cost); -- Verifiy the change SELECT * FROM pg_tablespace; |
Sometime we want to debug why ant build failed when executing a certain JUnit
Make sure your ant junit task look like the following
1 2 3 4 | <junit printsummary="withOutAndErr" haltonfailure="yes"> : : </junit> |
and not like
1 2 3 4 | <junit printsummary="yes" haltonfailure="yes"> : : </junit> |
1 2 3 4 | #!/bin/bash sync echo 1 > /proc/sys/vm/drop_caches service postgresql-9.3 restart |
If you’re running anything on the JVM (Java Virtual Machine) in production and you’ve never opened a Flight Recorder file, you’re leaving a free profiler on the table. Java Flight Recorder (JFR) is a low-overhead event recorder built into the JVM itself — no agent, no instrumentation, no extra dependency. You turn it on with a flag, you get back a .jfr file, you open it in JDK Mission Control and it tells you where your CPU time went, what the garbage collector (GC) was doing, which threads were contending on which locks, and which methods allocated the most memory. Originally a commercial JRockit feature, JFR was donated to OpenJDK as JEP 328 and has been free for production use since JDK 11. ☕
JFR is event-based. The JVM and the operating system fire events — GC pauses, thread state changes, exception throws, just-in-time (JIT) compilations, file I/O, socket reads — and JFR writes them to a ring buffer. You can also emit your own custom events from application code. The default profile aims for under 2% overhead, which is the magic number that makes it acceptable to leave running in production.
The simplest way to capture a recording is to ask for one when you launch the JVM. Add -XX:StartFlightRecording to your java command:
1 | java -XX:StartFlightRecording=duration=60s,filename=myapp.jfr,settings=profile -jar myapp.jar |
This records for 60 seconds and writes myapp.jfr to the working directory. Two settings templates ship with the JDK:
For a longer-running “black box” recording that always has the last few hours of data on disk:
1 | java -XX:StartFlightRecording=disk=true,maxage=6h,settings=default -jar myapp.jar |
Often you don’t want to restart the process — you want to attach to a JVM that’s already running and capture a slice. That’s what jcmd is for. First, find the process ID (PID):
1 | jcmd -l |
Then start, dump, and stop a recording on that PID:
1 2 3 4 5 6 7 8 9 10 11 | # Start a 2-minute profiling recording on PID 12345 jcmd 12345 JFR.start name=debug settings=profile duration=2m filename=/tmp/debug.jfr # Check what recordings are active jcmd 12345 JFR.check # Dump the current state of an in-progress recording without stopping it jcmd 12345 JFR.dump name=debug filename=/tmp/snapshot.jfr # Stop a recording explicitly (otherwise it stops at the duration) jcmd 12345 JFR.stop name=debug |
The JFR.dump trick is the one I reach for most often: keep a continuous low-overhead recording running, and when something interesting happens (a slow request, a memory spike), dump the in-flight buffer to a file for analysis. You get the events leading up to the moment, not just events from when you noticed.
A .jfr file is a binary log of events — you need a viewer. The canonical one is JDK Mission Control (JMC):
If you just want a quick text dump without firing up a graphical interface, the JDK ships a jfr command-line tool:
1 2 | jfr summary myapp.jfr # event counts and recording metadata jfr print --events CPULoad myapp.jfr # print all events of a given type |
IntelliJ IDEA Ultimate also opens .jfr files directly with a built-in viewer if you’d rather not install JMC.
JFR shines for the questions that a debugger or a print statement can’t answer cheaply:
It’s not a replacement for application performance monitoring (APM) tools like Datadog or New Relic, or for distributed tracing — JFR sees a single JVM, not a whole fleet. But for a deep look at what one process is doing, with overhead low enough to leave it running in production, nothing else in the Java ecosystem comes close. 🚀
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | SELECT R.TABLE_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE u INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS FK ON U.CONSTRAINT_CATALOG = FK.UNIQUE_CONSTRAINT_CATALOG AND U.CONSTRAINT_SCHEMA = FK.UNIQUE_CONSTRAINT_SCHEMA AND U.CONSTRAINT_NAME = FK.UNIQUE_CONSTRAINT_NAME INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE R ON R.CONSTRAINT_CATALOG = FK.CONSTRAINT_CATALOG AND R.CONSTRAINT_SCHEMA = FK.CONSTRAINT_SCHEMA AND R.CONSTRAINT_NAME = FK.CONSTRAINT_NAME WHERE -- THIS IS WHERE YOUR INTEREST IS (YOUR TABLE) U.COLUMN_NAME = 'THE_COLUMN_NAME' AND U.TABLE_CATALOG = 'THE_DB_NAME' AND U.TABLE_SCHEMA = 'THE_SCHEMA_NAME' AND U.TABLE_NAME = 'THE_TABLE_NAME' |
Create a postgres function to devide-and-conquer (iterate) your big query
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | TRUNCATE TABLE YOUR_NEW_BIG_TABLE; DROP FUNCTION IF EXISTS pg_iterator(); CREATE OR REPLACE FUNCTION pg_iterator() RETURNS void AS $BODY$ DECLARE vOffsetRecord INT; vTotal INT; vLimit INT; vOffset INT; BEGIN -- How many? -- select count(*) INTO currentRecord from YOUR_BIG_TABLE; -- 346,879,848 vTotal := 346879848; -- vTotal := 5000; vLimit := 100000; vOffset :=0; RAISE NOTICE 'DEBUG vTotal : %', vTotal; RAISE NOTICE 'DEBUG vLimit : %', vLimit; RAISE NOTICE 'DEBUG vOffset: %', vOffset; LOOP IF (vOffset >= vTotal) THEN EXIT; END IF; EXECUTE format('INSERT INTO YOUR_NEW_BIG_TABLE (id, language, hash) SELECT id, language, hash FROM YOUR_BIG_TABLE ORDER BY id LIMIT %s OFFSET %s;', vLimit, vOffset); RAISE NOTICE 'DEBUG vOffset: %', vOffset; vOffset := vOffset + vLimit; END LOOP; END$BODY$ LANGUAGE plpgsql VOLATILE COST 100; ALTER FUNCTION pg_iterator() OWNER TO postgres; SELECT pg_iterator(); |
1 2 3 4 5 6 | # minute (0-59), # | hour (0-23), # | | day of the month (1-31), # | | | month of the year (1-12), # | | | | day of the week (0=Sunday 1=Monday 2=Tuesday 3=Wednesday 4=Thursday 5=Friday 6=Saturday). # | | | | | commands |
The classic three-liner for adding a MySQL user, run from a mysql shell connected as root or another account with the CREATE USER privilege. Replace each placeholder with your own value.
1 2 3 | CREATE USER 'YOUR_USER_NAME'@'CONNECTING_FROM_WHERE' IDENTIFIED BY 'THIS_USER_PASSWORD'; GRANT ALL PRIVILEGES ON *.* TO 'YOUR_USER_NAME'@'CONNECTING_FROM_WHERE' WITH GRANT OPTION; FLUSH PRIVILEGES; |
The host part — CONNECTING_FROM_WHERE — is the bit most people get wrong on the first try. It tells MySQL which client addresses are allowed to authenticate with this account. Common values:
A few useful additions.
Don’t grant ALL ON *.* with GRANT OPTION to an app user. The grant above gives this user everything on every database, plus the ability to hand those privileges to other users. That’s effectively superuser. For an application account you almost always want a much tighter grant — restrict to the one database the app uses, and drop WITH GRANT OPTION:
1 2 | CREATE USER 'myapp'@'%' IDENTIFIED BY 'a-strong-password'; GRANT SELECT, INSERT, UPDATE, DELETE ON myappdb.* TO 'myapp'@'%'; |
Use GRANT ALL ON myappdb.* if your app needs schema changes (DDL) too. Reserve WITH GRANT OPTION for accounts whose actual job is to manage other users — not your application’s connection pool.
FLUSH PRIVILEGES isn’t needed here. One of the longest-running pieces of MySQL folklore. FLUSH PRIVILEGES is only needed when you modify the underlying mysql.user tables directly with INSERT/UPDATE. CREATE USER and GRANT already update the in-memory privilege tables, so the flush is a no-op. Harmless to leave in, but if you’ve been told it’s mandatory — it isn’t.
MySQL 8: the auth plugin changed. MySQL 8.0 made caching_sha2_password the default authentication plugin (it was mysql_native_password in 5.7). Most modern client libraries handle it fine, but older drivers or short-lived containers connecting to MySQL 8 sometimes throw “Plugin caching_sha2_password could not be loaded”. Two ways out: upgrade the client, or fall back to the old plugin per-user:
1 2 | CREATE USER 'legacy_app'@'%' IDENTIFIED WITH mysql_native_password BY 'a-strong-password'; |
localhost and 127.0.0.1 are two different host strings. A user defined as ‘foo’@’localhost’ can only connect over the Unix socket. A user defined as ‘foo’@’127.0.0.1’ can only connect over TCP loopback. They’re separate account rows in mysql.user. If you wonder why your app works in mysql but fails from a script that uses –protocol=tcp, this is usually it. Create both rows, or use ‘%’ if you don’t care about the path.
Companion commands you’ll want next.
1 2 3 4 5 6 7 8 9 10 11 | -- Change a user's password ALTER USER 'myapp'@'%' IDENTIFIED BY 'a-new-password'; -- See what a user is allowed to do SHOW GRANTS FOR 'myapp'@'%'; -- List all users and the host pattern they're tied to SELECT USER, host FROM mysql.user; -- Remove a user (drops every host pattern; for one specific host use 'name'@'host') DROP USER 'myapp'@'%'; |
And of course: if you’re choosing a database tool today and aren’t already on MySQL, take a look at MariaDB (a drop-in fork that follows similar SQL) or PostgreSQL (different syntax, but a noticeably more featureful default). For an existing MySQL deployment though, the recipe above is still exactly the right one. 🐬