I've been out of the Android development game for some time now. A little over a year, if I check the commit log on my projects. A friend's recent foray into this world encouraged me to look at refreshing my apps.
I have an app called WebsiteMonitor. The idea is that it polls a list of URLs and alerts you when any of them return a response code other than 200 (ok). This was inspired by my former job where I needed to make sure webservices were up and running at all times.
It had some serious limitations. First off, it was developed for Android 1.5. Second, it was using a widget to periodically poll, where the minimum refresh time is 1 hour, and doesn't alert you when your phone is sleeping. My current rating isn't the greatest, but what can you expect if I can't spend a lot of time on it, and it's pretty stale.
Well now the Android development landscape has changed significantly. The community appears to be way more active that it was a year ago with many more helpful tutorials and advice than there were when I first started. In pretty short order I was able to add quite a few features:
- custom ringtone
- enable notifications (persistent if you want)
- a polling service so it runs while your phone is idle
- less false negatives. This remains to be verified, but I think it's better
I haven't published it yet since I'm waiting for it to cook a while on my phone and a friend's. If it does ok over the next few days the plan is to put it up for download shortly. In the meantime, you can help test it or download the old version.
It's such a great advantage to have your vehicle maintenance documented.
- It's very helpful when it comes to selling.
- Prevents over-extending periods between maintenance (forgetting the last time you did an oil change).
My problem is that either I don't have my notebook on hand when I do the maintenance, or I forget, and by the time I get around to it, I can't remember what the odometer was at.
This has inspired my latest pet project, lper100km.com, which allows you to not only keep track of maintenance, but track your fuel economy across multiple vehicles on a mobile device. It's currently designed specifically for mobile so it doesn't look great on a full browser. The site is pretty basic right now, but functional. Features are added as I have time to implement them.
- Record fill ups and calculate fuel economy.
- Record maintenance
- Upload pictures of vehicles.
In no particular order, features under consideration are:
- Ability to use imperial values set as a user preference.
- Attach images to maintenance records.
- Multiple maintenance types per record. ie Oil and air filter in one entry.
- Plotting fuel economy, with markers for maintenance on the same graph.
- Print view of vehicle records.
- Full browser site.
- Better domain name?
Feel free to try it out and make suggestions.
I recently had an issue where one of my MySQL slaves repeatedly error'd on replication due to key collisions. The replication type was row based, which is much more strict that statement. In fact, if it had been statement based, a lot of these errors wouldn't have presented themselves and the slave would have continued on happily becoming more and more inconsistent.,
Because of the huge dataset and the speed of recovery required, I did not want to rebuild the entire database. I wanted to restore only the couple tables that were causing issues.
What I wanted to do was
- stop replication on a good slave and the problem slave at the same point
- dump the table (from the good slave, obviously)
- drop and import the dumped tables on the problem slave
- restart replication
Fortunately this is achievable with by stopping the slave to be fixed and then a minute or so later the source database, capturing the binlog and position and then issuing the following on the target database:
START SLAVE UNTIL MASTER_LOG_FILE='binlog.000001', MASTER_LOG_POS=123456; SELECT MASTER_POS_WAIT('binlog.000001', 123456);At this point, both databases should have had their slave processes halted at the same execution point and the dump and restore outlined above can be done. This reduced what would have been a 5 hour database copy into 15 minutes. Hopefully this will save someone else some time too.
Cloning a MySQL slave is typically very straight forward.
stop slaveon the donor slave and capture the slave status information
- Stop mysql on the donor
- Copy the database files from the donor to the new slave
- Start MySQL on the new slave
- Execute the change master statement to start the new slave's replication process
- Start mysql on the donor and allow replication to catch up
Simple right? It is, if you don't run into the scenario I managed to hit. Show slave status gives you a lot of information like this:
Master_Host: 10.10.10.10 Master_User: repl_user Master_Port: 3306 Connect_Retry: 60 Master_Log_File: binlog.002644 Read_Master_Log_Pos: 1015419943 Relay_Log_File: relay-log.000257 Relay_Log_Pos: 68175060 Relay_Master_Log_File: binlog.002643 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 887594041 Relay_Log_Space: 2448352803
This information is then matched into a change master statement. The most important values here are MASTER_LOG_FILE and MASTER_LOG_POS which tell the slave thread where to start replicating from. This will be the point where the donor slave was stopped before the copy. Now, you'd think that the master log file would correspond with the Master_Log_File value from show slave status. It doesn't. You want to use Relay_Master_Log_File. Most often, these log files are the same - if replication isn't lagging. But even in instances where the slave is not behind there is a small chance you'll catch it as the IO thread is getting the next binlog file. Now if you use the log file you think is correct, you'll be setting your replication to start too far ahead. Now, you may get lucky like me and the position won't exist in the binlog you set, and you'll get a replication IO error in my case, 1236 "Exceeded max_allowed_packet", instructing you to set the max_allowed_packet larger on the master which is misleading in this case.
CHANGE MASTER statement for the above slave status should be
CHANGE MASTER TO MASTER_LOG_FILE='binlog.002643' MASTER_LOG_POS=887594041The log position is the value from
Hopefully this will keep you from bludgeoning your forehead on your desk as I nearly did.