2015年5月12日 星期二

Upgrade MySQL (5.0 -> 5.6)

1.mysqldump 5.0 server data and, import to 5.6 server


2. let 5.0 be master and 5.6 be slave, replication


3. ensure all the sql statements  are correct


4. change 5.6 to master


NOTICE :

Some statement could execute by replication but generate error when change 5.6 to master
because sql_mode is strict sql mode

reference :
https://dev.mysql.com/doc/refman/5.0/en/sql-mode.html
https://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_sql_mode


examples :

CREATE TABLE `test2` (
`no` INT( 11 ) NOT NULL AUTO_INCREMENT ,
`data1` INT( 11 ) NOT NULL ,
`PS` TINYTEXT NOT NULL ,
`sdate` DATETIME NOT NULL ,
PRIMARY KEY ( `no` )
)
A.
INSERT INTO test2( `no` , `data1` , `PS` , `sdate` ) 
VALUES (
'', 1, "testps", '2015-05-12 18:00:00'
)
#1366 - Incorrect integer value: '' for column 'no' at row 1

B.
INSERT INTO test2( `no` , `data1` , `sdate` ) 
VALUES (
NULL , 1, '2015-05-12 18:00:00'
)

#1364 - Field 'PS' doesn't have a default value

C.
INSERT INTO test2( `no` , `data1` , `sdate` ) 
VALUES (
NULL , 1, '2015-05-12 18:00:00'
)

#1292 - Incorrect datetime value: '' for column 'sdate' at row 1

D.
INSERT INTO test2( `no` , `data1` , `PS` , `sdate` ) 
VALUES (
NULL , 1, 'pstest', '0000-13-00 00:00:00'
)

 #1292 - Incorrect datetime value: '0000-13-00 00:00:00' for column 'sdate' at row 1 


In none-strict sql mode or in 5.0, those statements will be executed correctly.

The correct form should be

INSERT INTO `test2` (`no`, `data1`, `PS`, `sdate` ) VALUES (NULL, 1, 'pstest', '0000-00-00 00:00:00');
or
INSERT INTO `test2` (`no`, `data1`) VALUES (0, 1, 'pstest', '0000-00-00 00:00:00');
or
INSERT INTO `test2` (`data1`) VALUES (1, 'pstest', '0000-00-00 00:00:00');


To disable strict_sql_mode (reference)

 1. check default sql_mode by

mysql> select @@sql_mode;
+------------------------+
| @@sql_mode       |
+------------------------+
| NO_ENGINE_SUBSTITUTION, STRICT_TRANS_TABLES |
+------------------------+

 2. in my.cnf, change

sql_mode="NO_ENGINE_SUBSTITUTION, STRICT_TRANS_TABLES"
to
sql_mode="NO_ENGINE_SUBSTITUTION"









2015年5月8日 星期五

Linux daemonize

1. from stackoverflow
http://stackoverflow.com/questions/17954432/creating-a-daemon-in-linux

Sample Source Code
/*
 * daemonize.c
 * This example daemonizes a process, writes a few log messages,
 * sleeps 20 seconds and terminates afterwards.
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 

static void skeleton_daemon()
{
    pid_t pid;

    /* Fork off the parent process */
    pid = fork();

    /* An error occurred */
    if (pid < 0)
        exit(EXIT_FAILURE);

    /* Success: Let the parent terminate */
    if (pid > 0)
        exit(EXIT_SUCCESS);

    /* On success: The child process becomes session leader */
    if (setsid() < 0)
        exit(EXIT_FAILURE);

    /* Catch, ignore and handle signals */
    //TODO: Implement a working signal handler */
    signal(SIGCHLD, SIG_IGN);
    signal(SIGHUP, SIG_IGN);

    /* Fork off for the second time*/
    pid = fork();

    /* An error occurred */
    if (pid < 0)
        exit(EXIT_FAILURE);

    /* Success: Let the parent terminate */
    if (pid > 0)
        exit(EXIT_SUCCESS);

    /* Set new file permissions */
    umask(0);

    /* Change the working directory to the root directory */
    /* or another appropriated directory */
    chdir("/");

    /* Close all open file descriptors */
    int x;
    for (x = sysconf(_SC_OPEN_MAX); x>0; x--)
    {
        close (x);
    }

    /* Open the log file */
    openlog ("firstdaemon", LOG_PID, LOG_DAEMON);
}
int main()
{
    skeleton_daemon();

    while (1)
    {
        //TODO: Insert daemon code here.
        syslog (LOG_NOTICE, "First daemon started.");
        sleep (20);
        break;
    }

    syslog (LOG_NOTICE, "First daemon terminated.");
    closelog();

    return EXIT_SUCCESS;
}

  • Compile the code: gcc -o firstdaemon daemonize.c
  • Start the daemon: ./firstdaemon
  • Check if everything is working properly: ps -xj | grep firstdaemon
  • The output should be similar to this one:
+------+------+------+------+-----+-------+------+------+------+-----+
| PPID | PID  | PGID | SID  | TTY | TPGID | STAT | UID  | TIME | CMD |
+------+------+------+------+-----+-------+------+------+------+-----+
|    1 | 3387 | 3386 | 3386 | ?   |    -1 | S    | 1000 | 0:00 | ./  |
+------+------+------+------+-----+-------+------+------+------+-----+
What you should see here is:
  • The daemon has no controlling terminal (TTY = ?)
  • The parent process ID (PPID) is 1 (The init process)
  • The PID != SID which means that our process is NOT the session leader
    (because of the second fork())
  • Because PID != SID our process can't take control of a TTY again
Reading the syslog:
  • Locate your syslog file. Mine is here: /var/log/syslog
  • Do a: grep firstdaemon /var/log/syslog
  • The output should be similar to this one:
  firstdaemon[3387]: First daemon started.
  firstdaemon[3387]: First daemon terminated.

2. from redis github sample
https://github.com/antirez/redis/blob/unstable/src/redis.c




void daemonize(void) {

int fd;


if (fork() != 0) exit(0); /* parent exits */

setsid(); /* create a new session */


/* Every output goes to /dev/null. If Redis is daemonized but

* the 'logfile' is set to 'stdout' in the configuration file

* it will not log at all. */

if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {

dup2(fd, STDIN_FILENO);

dup2(fd, STDOUT_FILENO);

dup2(fd, STDERR_FILENO);

if (fd > STDERR_FILENO) close(fd);

}

}



  • The output should be similar to this one:
+------+------+------+------+-----+-------+------+------+------+-----+
| PPID | PID  | PGID | SID  | TTY | TPGID | STAT | UID  | TIME | CMD |
+------+------+------+------+-----+-------+------+------+------+-----+
|    1 | 17508| 17508| 17508| ?   |    -1 | S    | 1000 | 0:00 | ./  |
+------+------+------+------+-----+-------+------+------+------+-----+

the pid = sid




2015年4月20日 星期一

Linux Shared Library Informantion

1.get .so file info
(http://unix.stackexchange.com/questions/58846/viewing-linux-library-executable-version-info)

Get all Info
readelf -a -W elffile

Example :
readelf -a -W  libmysqlclient.so.16


readelf -d  /path/to/library.so |grep SONAME

Example :
readelf -d libmysqlclient.so.16 | grep SONAME
 0x000000000000000e (SONAME)             Library soname: [libmysqlclient.so.16]


2. check dependencies

ldd  /path/to/library.so

Example:
ldd libmysqlclient.so.16
        linux-vdso.so.1 =>  (0x00007fff9ebae000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f47b438b000)
        libnsl.so.1 => /lib64/libnsl.so.1 (0x00007f47b4171000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f47b3eed000)
        libssl.so.10 => /usr/lib64/libssl.so.10 (0x00007f47b3c81000)
        libcrypto.so.10 => /usr/lib64/libcrypto.so.10 (0x00007f47b38a0000)
        libz.so.1 => /lib64/libz.so.1 (0x00007f47b368a000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f47b32f6000)
        libfreebl3.so => /lib64/libfreebl3.so (0x00007f47b307c000)
        libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007f47b2e38000)
        libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007f47b2b52000)
        libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f47b294d000)
        libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f47b2721000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f47b251d000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f47b4951000)
        libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007f47b2311000)
        libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f47b210e000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f47b1ef4000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f47b1cd6000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f47b1ab7000)

3. Static、Shared Dynamic and Loadable Libraries
(http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html)

  1. Static libraries (.a): Library of object code which is linked with, and becomes part of the application.
  2. Dynamically linked shared object libraries (.so): There is only one form of this library but it can be used in two ways.
    1. Dynamically linked at run time but statically aware. The libraries must be available during compile/link phase. The shared objects are not included into the executable component but are tied to the execution.
    2. Dynamically loaded/unloaded and linked during execution (i.e. browser plug-in) using the dynamic linking loader system functions.


2015年3月25日 星期三

MySQL Partition ( VER 5.6.6 up)

1. Origin Table

CREATE TABLE `TEST` (
  `NO` int(11) NOT NULL AUTO_INCREMENT,
  `TIME` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `ID` varchar(32) NOT NULL,
  `EVENTNO` int(11) NOT NULL DEFAULT '0',
  `VALUENO` int(11) NOT NULL DEFAULT '0',
  `VALUE` bigint(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`NO`),
  KEY `ID` (`ID`),
  KEY `EVENTNO` (`EVENTNO`),
  KEY `VALUENO` (`VALUENO`)
) ENGINE=MyISAM AUTO_INCREMENT=0

 ALTER TABLE TEST DROP PRIMARY KEY, ADD UNIQUE KEY `ID_EVENTNO_VALUENO` (`ID`,`EVENTNO`,`VALUENO`), ADD UNIQUE KEY `NO_EVENTNO` (`NO`,`EVENTNO`), DROP KEY `VALUENO`;
ALTER TABLE TEST PARTITION BY HASH(`EVENTNO`) PARTITIONS 10;


PS : We could  also DROP KEY `ID` and `EVENTNO` ...

Use EVENTNO to be Hash Key into 10 partition


2. Explain

EXPLAIN PARTITIONS SELECT VALUE FROM TEST WHERE ID = 'AAAA' AND EVENTNO = 200015 AND VALUENO = 10008;

+----+-------------+-----------------+------------+-------+-------------------------------+--------------------+---------+-------------------+------+-------+
| id | select_type | table           | partitions | type  | possible_keys                 | key                | key_len | ref               | rows | Extra |
+----+-------------+-----------------+------------+-------+-------------------------------+--------------------+---------+-------------------+------+-------+
|  1 | SIMPLE      | TEST | p5         | const | ID_EVENTNO_VALUENO,ID,EVENTNO | ID_EVENTNO_VALUENO | 74      | const,const,const |    1 | NULL  |
+----+-------------+-----------------+------------+-------+-------------------------------+--------------------+---------+-------------------+------+-------+

partitions = p5      ==> we use EVENTNO to partition
key  ID_EVENTNO_VALUENO  
rows = 1 , only 1 row, good index



3. Partition Rule

A: HASH (N) ,  N must be an integer

B:  All columns used in the partitioning expression for a partitioned table must be part of every unique key that the table may have.
(https://dev.mysql.com/doc/refman/5.6/en/partitioning-limitations-partitioning-keys-unique-keys.html)

也就是說 拿來當 Partition 的Key, 必須存在在所有的 Primay / Unique Key中


2015年2月13日 星期五

GenyMotion Google Play and ARM(CPU_ABI_INCOMPATIBLE) Support

1.  Google Play

https://gist.github.com/wbroek/9321145

Google Apps for Android 5.0 (https://www.androidfilehost.com/?fid=95784891001614559 - gapps-lp-20141109-signed.zip)
Google Apps for Android 4.4.4 (https://www.androidfilehost.com/?fid=23501681358544845 - gapps-kk-20140606-signed.zip)
Google Apps for Android 4.3 (https://www.androidfilehost.com/?fid=23060877490000124 - gapps-jb-20130813-signed.zip)
Google Apps for Android 4.2 (https://www.androidfilehost.com/?fid=23060877490000128 - gapps-jb-20130812-signed.zip)
Google Apps for Android 4.1 (https://www.androidfilehost.com/?fid=22979706399755082 - gapps-jb-20121011-signed.zip)
Google Apps for Android 2.3.7 (http://www.mediafire.com/download/bs063kb0m742o5l/gapps-gb-20131027-signed.zip - gapps-gb-20131027-signe.zip)


2. Install ARM
http://filetrip.net/dl?4SUOrdcMRv




Other Ref:

http://forum.xda-developers.com/showthread.php?t=2528952

2015年1月16日 星期五

Get Other App Status in Android

1. Before API Level 21 (Lolipop , 5.0 )


ref:
http://stackoverflow.com/questions/22500959/detect-when-other-application-opened-or-launched

http://developer.android.com/reference/android/app/ActivityManager.html

getRunningAppProcesses()
Returns a list of application processes that are running on the device.

getRunningTasks(int maxNum)
This method was deprecated in API level 21. As of LOLLIPOP, this method is no longer available to third party applications: the introduction of document-centric recents means it can leak person information to the caller. For backwards compatibility, it will still retu rn a small subset of its data: at least the caller's own tasks, and possibly some other tasks such as home that are known to not be sensitive.


A : Get Running Processes Lists

ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfo = am.getRunningAppProcesses();

for (int i = 0; i < runningAppProcessInfo.size(); i++) {
  if(runningAppProcessInfo.get(i).processName.equals("com.the.app.you.are.looking.for") {
    // Do you stuff
  }
}

B: Get Top Task ( Foreground Tasks)

public static boolean isForeground(Context ctx, String myPackage){
    ActivityManager manager = (ActivityManager) ctx.getSystemService(ACTIVITY_SERVICE);
    List< ActivityManager.RunningTaskInfo > runningTaskInfo = manager.getRunningTasks(1); 

    ComponentName componentInfo = runningTaskInfo.get(0).topActivity;
    if(componentInfo.getPackageName().equals(myPackage)) {
        return true;
    }       
    return false;
}

2. After API Level 21 (Lolipop)


the getRunningTasks is deprecated


other approach :
getAppTasks 
http://developer.android.com/reference/android/app/ActivityManager.html#getAppTasks%28%29


http://www.intertech.com/Blog/android-5-api-changes-getapptasks/

2015年1月14日 星期三

WebView Size Problem in Andorid 4.4

1. the webpage will over screen size

ref :
https://developer.android.com/guide/webapps/migrating.html


add :
WebSettings settings = webView.getSettings();
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);





Other:
set webview background color

myWebView.setBackgroundResource(Color.TRANSPARENT);
myWebView.setBackgroundColor(Color.TRANSPARENT);