Saturday, May 31, 2014

How to export and import MySQL database

You can export the MySQL database with schema table definitions and data separated. Here is a simple bash shell script that will export an database.

# file: database-export.sh
DB_NAME=mydb
DB_SCHEMA_FILE=mydb.sql
DB_DATA_FILE=mydb-data.sql
DB_USERNAME=root
DB_PASSWORD=secret

# export schema only from mysql
 

echo "`date` Exporting database $DB_NAME schema to $DB_SCHEMA_FILE"
mysqldump --no-data --routines -u $DB_USERNAME -p$DB_PASSWORD $DB_NAME > $DB_SCHEMA_FILE

# export data only from mysql
echo "`date` Exporting database $DB_NAME data to $DB_DATA_FILE"
mysqldump --single-transaction --quick --no-autocommit --no-create-info --extended-insert=false -u $DB_USERNAME -p$DB_PASSWORD $DB_NAME > $DB_DATA_FILE


echo "`date` Done."


The schema export with "--routines" will export stored proc as well. When exporitng data you have to be little more careful. The "--single-transaction" will ensure your data is good. The "--no-autocommit" can really speed up your import later on certain OS.

Now to import these files back, you can create an empty database and then run the following.

# file: database-import.sh
# import schema and data into mysql
echo "`date` Importing Schema $DB_SCHEMA_FILE into $DB_NAME"
mysql -f -u $DB_USERNAME -p$DB_PASSWORD $DB_NAME < $DB_SCHEMA_FILE
echo "`date` Importing DATA $DB_DATA_FILE into $DB_NAME"
mysql -f -u $DB_USERNAME -p$DB_PASSWORD $DB_NAME < $DB_DATA_FILE

echo "`date` Done."


The import with "-f" option will allow you to continue even if you already have duplicated data in the tables; it will simply ignore and continue.

These two combo commands will allow you to quicly backup and restore a MySQL database.

Enjoy.

PS: I have come to learn that "mysqldump" with procedures will insert an extra line like "DEFINER 'user'@'hostname'", and it may create problem if you use different users to export/import or even run the application! Unfortunately there is no exclude from the "mysqldump" tool. So you have to manually strip that off if that's creating a problem for you.

mysqldump --no-data --routines -u $DB_USERNAME -p$DB_PASSWORD $DB_NAME | perl -pi -e 's/DEFINER="\w+"@"\w+" //g' > $DB_SCHEMA_FILE

You can vote the issue here: http://bugs.mysql.com/bug.php?id=24680

Thursday, April 17, 2014

How to enable MySQL query monitoring


Do you need to monitor any SQL statements passing through your MySQL server? You would need to turn on the server logging. Edit your my.cnf file and add these:

log-output=FILE
general-log=1
general_log_file=mysql-general.log


You also need to restart the database server after these changes.

Wednesday, April 16, 2014

Be careful with Java Path.endsWith(String) usage

If you need to compare the java.io.file.Path object, be aware that Path.endsWith(String) will ONLY match another sub-element of Path object in your original path, not the path name string portion! If you want to match the string name portion, you would need to call the Path.toString() first. For example

// Match all jar files.
Files.walk(dir).forEach(path -> {
if (path.toString().endsWith(".jar"))
System.out.println(path);
});

With out the "toString()" you will spend many fruitless hours wonder why your program didn't work.

Monday, April 14, 2014

How to disable MySQL case sensitive with table names in queries

My latest install of MySQL 5.16 on Windows 7 is case sensitive with table names. I much prefer it's case in-sensitive for faster typing and adhoc queries. To do that, I need to edit the my.cnf file (Try running "mysql --help" and it will tell you where it is.)

At the end of the file, add this line:

lower_case_table_names = 1

Tuesday, April 8, 2014

How to setup remote debug with WebLogic Server and Eclipse

Here is how I enable remote debugging with WebLogic Server (11g) and Eclipse IDE. (Actually the java option is for any JVM, just the instruction here is WLS specific.)

1. Edit <my_domain>/bin/setDomainEnv.sh file and add this on top:

JAVA_OPTIONS="$JAVA_OPTIONS -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"

The suspend=n will start your server without wait for you to connect with IDE. Server usually started with bunch of waiting threads and you can connect with an IDE any any time. You then try to place a break point and fetch a new HTTP request etc to initiate a thread to go into the code breakponit. If you don't want the WLS to wait before fully started, then set it to suspend=y instead.

2. Start/restart your WLS with <my_domain>/bin/startWebLogic.sh

3. Once WLS is running, you may connect to it using Eclipse IDE. Go to Menu: Run > Debug Configuration ... > Remote Java Application and create a new entry. Ensure your port number is matching to what you used above.

Read more java debugging option here: http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#DebuggingOptions

Now on the IDE Eclipse side, you can connect to your WLS server with the following instruction:

1. In Eclipse menu, select Run > Debug Configuration ...
2. On left side, select Remote Java Application, and then press the + button to create a new configuration.
3. On the right side you can fill in the server info such as hostname and port number.
4. Click Debug button


UPDATE (10/30/14):
Remember each remote debug setup is per JVM and requires a unique port. So how to set each WebLogic Managed Server with unique debug port? You can easily do this by updating your line above to this:

DEBUG_PORT=${DEBUG_PORT:=8000}
JAVA_OPTIONS="$JAVA_OPTIONS -Xrunjdwp:transport=dt_socket,address=$DEBUG_PORT,server=y,suspend=n" 

Now you can start managed server like this to change the port in a Bash shell by change to your domain directory first, then run:

bash>DEBUG_PORT=8001 bin/startManagedWeblogic.sh my_server_name

Saturday, April 5, 2014

Creating your own loop structure in Java 8 lambda

Java doesn't have an easy construct of repeat something N number of times. We can make a for loop of course, but many times we don't even care about the variable that we created in the loop. We just want repeat N times of some code and that's it. With the lambda available in Java 8, you may attempt something like this:

public class RepeatDemo {
    public static void main(String[] args) {

        // One liner repeat
        repeat(10, () -> System.out.println("HELLO"));


        // Multi-liners repeat

        repeat(10, () -> {
            System.out.println("HELLO");
            System.out.println("WORLD");
        });
    }
   
    static void repeat(int n, Runnable r) {
        for (int i = 0; i < n; i++)
            r.run();
    }
}



Probably not as eye pleasing or straight forward as the good fashion for-loop, but you do get rid of the unnecessary loop variable. Only if Java 8 would go extra mile and treat the lambda argument in method with sugar syntax, then we could have it something like the Scala/Groovy style, which makes code more smoother. For example:

        // Wouldn't this be nice to have in Java?

        repeat(10) {
            System.out.println("HELLO");
            System.out.println("WORLD");
        }


Hum....