פלאנט תוכנה חופשית בישראל (Planet FOSS-IL)

20 מאי, 2012

Baruch Siach

linux kernel module parameters

Setting Linux kernel module parameters

Many Linux kernel modules have parameters that can be set at load time, boot time, and sometimes run-time. In the following I'll demonstrate each method.

Setting module parameter at load time

The easiest way to load kernel modules at run time is using the modprobe command. To set a module parameter put the parameter name and value in the modprobe command line:

modprobe foo parameter=value

The command modinfo lists the parameters that a given kernel module accepts, with the expected type of each parameter. For example, on my Linux 3.2 based system the command modinfo ambassador shows the following parameters info:

parm:           debug:debug bitmap, see .h file (ushort)
parm:           cmds:number of command queue entries (uint)
parm:           txs:number of TX queue entries (uint)
parm:           rxs:number of RX queue entries [4] (array of uint)
parm:           rxs_bs:size of RX buffers [4] (array of uint)
parm:           rx_lats:number of extra buffers to cope with RX latencies (uint)
parm:           pci_lat:PCI latency in bus cycles (byte)

Simple values of type byte or uint are represented by a number:

modprobe ambassador debug=1

Array values are set using a comma separated list of values:

modprobe ambassador rxs=1000,2000,3000,4000

String (charp) values are set using a string:

modprobe parport_pc init_mode=epp

Setting module parameters at boot time

When a module is compiled into the kernel you can't load it at run time, and you can't set its parameters either. You can, however, set the module parameters from the kernel command line as described in Documentation/kernel-parameters.txt. The equivalent of the modprobe commands above, are the following strings in the kernel command line:

ambassador.debug=1

ambassador.rxs=1000,2000,3000,4000

parport_pc.init_mode=epp

Setting module parameters at run-time

Sometimes a kernel modules allows setting a parameter at run time. In this case you'll find the parameter under /sys/module/modulename/parameters/, with writable file permissions. The debug parameter of the ambassador module is an example of such a parameter. Set a value to this parameter with a simple echo command:

echo -n 1 > /sys/module/ambassador/parameters/debug

20 מאי, 2012 11:05 AM

Yehuda Bar-Nir

השרות הנסיוני לתכנון נסיעה בתח”צ עלה לאויר

פחות משבוע אחרי הפרסום הראשון של נתוני התחבורה הציבורית בפורמט תיקני, עלה לאויר שרות חופשי לתכנון מסלולי נסיעה המבוסס על הנתונים אלה. ניתן לתכנן נסיעה בתחבורה ציבורית מכל מקום לכל מקום בארץ, אם כי לא כל חברות התח”צ מכוסות. בולטת בהעדרה רכבת-ישראל. השרות הוא נסיוני, והכתובת והשרת יוחלפו בקרוב. בנתיים מוזמנים לנסות ולשלוח תגובות למטה.

תכנון מסלול לדוגמה

שימו לב! השרות מוגש as-is. אין שום הבטחה לתקינות הנתונים מבחינת האפשרות לנסוע במסלול, יעילות המסלול, זמנים, מספרי הקוים, או מחיר הנסיעה (אם וכאשר יפורסם).
שוב תודה לחברי ומנהלי עמותת המקור על התמיכה בפרויקט.

20 מאי, 2012 03:28 AM

19 מאי, 2012

Hetz Ben Hemo

‫כמה מילים על Coreboot ועל יצרני לוחות אם‬

‫הנה סיטואציה שידועה לכל איש IT שמנהל איזה שרת או שתיים (או יותר). אתה מחבר את הכבלים, לוחץ על כפתור ה-Power ועד שתקבל מצב שמערכת ההפעלה המותקנת עולה – יחלפו לפחות 2-4 דקות, ולא חשוב כמה השרת שלך חזק או עוצמתי, בין אם יש לו 2 ג’יגהבייט זכרון או 1 טרהבייט (אם כבר, ככל שיש [...]‬

הטקסט המלא

19 מאי, 2012 07:27 PM

Yehuda Bar-Nir

חישוב מסלול נסיעה בתחבורה ציבורית

משרד התחבורה החל לפרסם לפני כשבוע מאגר מידע חדש הכולל לוחות זמנים ונתיבים של התחבורה הציבורית בארץ. המאגר מפורסם לפי תקן פתוח של גוגל שנקרא GTFS. במסגרת שיתוף פעולה של מספר חברים ברשימת התפוצה של המקור, הקמנו פיילוט שמדגים את יכולות המאגר. הקוד בפיילוט מבוסס על פרויקט OpenTripPlanner. תודה לירון על עבודת התרגום, ולשאר החברים על העידוד והתמיכה.

עד להקמת שרת ציבורי, ניתן להתרשם מצילומי המסך:

מסלול שלם:
מסלול שלם

התמקדות על מקטעים:

" />
" />
" alt="התמקדות על מקטעים" />

גרסה להדפסה:

" />
" />
" alt="גרסה להדפסה" />

ההסבר בהמשך מיועד למי שרוצה להקים שרת. לא למי שרוצה לחשב מסלול !! (מה שנקרא: Don’t try this at home).

להקמת השרת, יש לבצע את הפעולות הבאות: (זה הרקע. הקוד בפסקה הבאה מבצע את הפעולות)

להוריד ולפתוח את הקוד של OpenTripPlanner (גודל הקובץ כ 90MB) וליצור קישור סימבולי ל / .
להוריד ולפתוח קובץ Open Street Map של ישראל מהאתר cloudmade.com (גודל הקובץ 22MB).
למצוא את כתובת קובץ ה GTFS מאתר מאגרי המידע של הממשלה, ולהוריד אותו. מכוון שהקובץ מוגש (זמנית?) משרת ftp ולא http, צריך לארח אותו מחדש על שרת אחר. בדוגמאות הקוד בהמשך האירוח הוא בשרת מקומי

$ mkdir ~/GTFS
$ cd ~/GTFS
$ curl -L -O "http://maps5.trimet.org/otp-dev/otp.zip"
$ curl -L -O "http://downloads.cloudmade.com/asia/western_asia/israel/israel.osm.bz2"
$ curl -L -O "ftp://199.203.58.18/israel-public-transportation.zip"
# !! replace IP above with correct IP
$ unzip otp.zip
$ bunzip2 israel.osm.bz2
$ sudo ln -s ~/GTFS/otp /
$ ln -s ~/GTFS/israel.osm /otp/cache/osm/
$ sudo cp  ~/GTFS/israel-public-transportation.zip /var/www/html/
# replace /var/www/html/ with your local http server root if applicable

יש לערוך מספר קבצי הגדרות:

$ vi /otp/graph-builder.xml
# Line 13, change URL of gtfs.zip to the http://localhost/israel-public-transportation.zip
#              (or whatever URL you placed the file in)
# Line 40, change file name of OSM from or-wa.osm to israel.osm (just file part)
$ vi /otp/bin/build-graph.sh
# Line 1, change -Xmx2048m to -Xmx6114m. If you have more memory, put as much as possible
$ vi /otp/bin/start-server.sh
# Line 1, change -Xmx2048m to -Xmx4096m. If you have more memory, put as much as possible

בניית הגרף (משלב נתוני OSM עם נתוני תח”ץ)

$ cd /otp
$ bin/build-graph.sh >& ~/GTFS/build-graph.err
# might take 15-30 minutes depending on processor power and memory
$ ls -l /otp/Graph.obj
# should be around 1GB

אחרי הריצה חשוב לוודא בלוג שאין תעופה בגלל חוסר זכרון !!

עכשיו אפשר להריץ את השרת האפליקטיבי:

$ cd /otp
$ bin/start-server.sh
# Wait for line: "Winstone Servlet Engine v0.9.10 running..."

עכשיו אפשר לפתוח דפדן לכתובת : http://localhost:8080/opentripplanner-webapp/index.html (אם השרת אינו מקומי, להחליף localhost בכתובת השרת). ולנסות לחשב מסלול.

תרגום לעברית:
לבדוק האם הקובץ ‎/otp/webapps/opentripplanner-webapp/js/otp/locale/Hebrew.js‏ קיים. אם לא, להוריד אותו מכאן ולשמור בנתיב הנ”ל. אחר-כך, יש לבצע מספר תיקונים בקוד:

$ vi /otp/webapps/opentripplanner-webapp/index.html
# line 2, add 'dir="rtl"' to html tag
# line 53, duplicate this line and change file name to "js/otp/locale/Hebrew.js"
$ vi /otp/webapps/opentripplanner-webapp/js/otp/config.js
# line 12, change otp.locale.English to otp.locale.Hebrew (at end of line)

עכשיו לרפרש את הדפדפן ולהנות מההמשק העברי. יתכן שתתקבל הודעה על כשלון בחישוב המסלול. במקרה זה, יש לבחור תאריך חדש לחישוב בתחום המכוסה על-ידי הקובץ (יום הורדת הקובץ ועד שבועיים קדימה)

19 מאי, 2012 06:53 PM

Arie Skliarouk

adaptec CLI management tool

Recently I had to install adaptec CLI management tool on an ubuntu 8.10 amd64 server. Despite the fact that aacraid driver is present in kernel, it took me a lot of time to find the management tools that allow to see the RAID status and manipulate it from command line. There are several names for the tools: afacli, aaccli, afaapps, afa-apps-snmp, arcconf, hrconf... oh my!
After I found the necessary tools (64bit arch), I packaged them into a tiny deb package adaptec-utils_0.0.1_amd64.deb, which can be downloaded from here: DELETED_AS_REDISTRIBUTION OF BINARIES_IS_PROHIBITED_BY_ADAPTEC

Also, I wrote a simple monitoring script (included in the deb package) that checks the state of the Adaptec RAID system and sends out an email if any of the published indicators is wrong (battery, failed disks, etc). The script can be downloaded from here: http://t11.mine.nu/adaptec-utils/adaptec_check.sh

Note that the script requires proprietary binary files to be installed. See the beginning of the script for the details.

19 מאי, 2012 02:43 PM

Guy Sheffer

SvxlinkWrapper – Wrapper for SvxLink to provide additional functionally such as QSO logging and auto-connect

Hey all,

A short post to announce a small piece of software I released today on github for the ham radio people.
I give you SvxlinkWrapper, this wrapper sits on top of Svxlink‘s stdout and stdin and processes it with python. Making it easy to add more advance features to Svxlinik. Since Svxlink is written in C++ and takes a while to compile, this wrapper really speeds up development. Furthermore, it uses straight.plugin making its simple to write more modules by extending SvxlinkwrapperModule and placing it in the modules folder.

Currently the to modules that SvxlinkWrapper has are for auto-connect to Echolink nodes on startup and another for a QSO logger for Echolink connections. There is also a module that should let you send commands over the Echolink chat, if you extend it. This lets me open and close repeater connections directly from the Echolink chat box.

Thats it for today, now that I have more free time, I hope to publish more things, 73


Full text

19 מאי, 2012 12:12 PM

Shlomi Fish

Tel Aviv Perl Mongers Meeting on 30 May, 2012

19 מאי, 2012 09:32 AM

18 מאי, 2012

Hetz Ben Hemo

‫על Core Boot, Thunderbolt ו..אינטל‬

‫הנה משהו שלא רציתי לגלות בקשר לתכנון שרת שאני מבצע: חשבתי להכניס הפתעה מסויימת, אולם לצערי נראה שזה יהיה בעייתי. הטכנולוגיה שרציתי להכניס לשרת היא Thunderbolt. למי שלא מכיר, זהו פתרון של חיבור סריאלי חיצוני שעליו עובר ממשק PCI Express, ובתרגום לעברית: Thunderbolt הוא ממשק סריאלי המאפשר חיבור ציודים שצורכים המון נתונים בחיבור טורי. מהירות [...]‬

הטקסט המלא

18 מאי, 2012 02:03 PM

Amir Aharoni

מחשב

איך יודעים שעובדי גוגל לא משתמשים בשירותי גוגל בעברית?

נכנסים לשירות „כונן Google” החדש. במסך הפתיחה כתוב:

כונן Google זמין עבור:

  • מחשב ו-Mac
  • Chrome OS
  • iPhone ו-iPad (בקרוב)
  • מכשירי Android

מחשב ו-Mac, אתם מבינים? גם מחשב, וגם Mac. ואם נדבר ברצינות, אז הכוונה כנראה ל־PC. ליתר דיוק, למה שמשתמשי Mac, המזלזלים במשתמשי מערכות ההפעלה אחרות עוד יותר מכמה שאני מזלזל בהם, קוראים לו „PC”. כלומר, מחשב עם מערכת ההפעלה Windows.

התרגום הגרוע הזה מציף כמה בעיות. הראשונה היא ש־PC, מחשב אישי, זה לא רק Windows. גם מחשבי עם Mac, תתפלאו, הם מחשבים אישיים. וגם מחשבים עם גנו/לינוקס. אז כן, נכון ש־„PC” הוא כינוי נפוץ ל־Windows, אבל הוא לא נכון וצריך להפסיק להנציח אותו.

הבעיה השנייה והחמורה יותר היא שגוגל מאפשרת לתרגומים גרועים כאלה להתפרסם. ושזה קורה, פעם אחר פעם, אף־על־פי שעובד בכיר בגוגל ישראל שדיברתי אתו על כך פעם אמר לי שגוגל לא מקבלת תרגומים מהקהילה, כי יש לה מתרגמים משלה שעושים עבודה טובה. „זה חשוב שזה יהיה טוב,” הוא אמר, „כי יש המון לקוחות ואסור שיהיו שם טעויות”. אז הנה, עובדה, יש טעויות.

אל תבינו מזה, חלילה, שאני קורא לגוגל לפטר את המתרגמת שעשתה את זה. בשום פנים ואופן לא. היא כנראה עושה עבודה רבה, קשה ואיכותית. אבל גוגל תעשה טובה למתרגמת הזאת, לחברה עצמה וללקוחותיה אם היא תשנה את הגדרת התפקיד שלה. היא צריכה להיות מאשרת תרגומים ולא מתרגמת. והתרגומים עצמם צריכים להגיע מהקהילה. כלומר, מאנשים אכפתיים שאוהבים את מוצרי גוגל ואת השפה העברית. כך, פחות או יותר, עובדים טוויטר ומוזילה. (ויקיפדיה ליברלית עוד יותר ומכניסה תרגומים מהציבור כמעט בלי ביקורת, אבל נעזוב את זה.)

ועוד דבר שזה אומר הוא מה שאמרתי בתחילה, ומה שאמרתי כבר פעמים רבות בעבר: עובדי גוגל ישראל לא משתמשים בשירותי גוגל בעברית. אחרת הם היו שמים לב לשטות הזאת. כשאני שואל אותם למה הם לא משתמשים במוצרים של החברה שלהם בעברית, הם אומרים לי שזה נוח יותר באנגלית. אבל זאת בדיוק הבעיה, חֶבְרֶה: זה צריך להיות נוח באותה מידה ואתם האנשים הנכונים ביותר שיכולים לתקן את זה. אבל כדי לתקן תקלה, צריך קודם לראות אותה, ואם לא תשתמשו בשירותי גוגל בעברית, לעולם לא תראו אותה. אני קורא לזה „פרדוקס תרגום התכנה”.

לו הייתי לארי פייג׳, הייתי מקבל את ההחלטה העסקית הנכונה לחברה ומבטל בחשבונות של עובדי גוגל ישראל את האפשרות להשתמש באתרי גוגל בשפה שאינה עברית או ערבית. (או שפה אחרת לעובדי גוגל במדינות אחרות.)

וכן, יש גם את הבעיה הבלתי־חשובה הזאת שכונן גוגל כנראה לא עובד במערכות הפעלה שאינן Windows ו־Mac, אבל זה לא מעניין אותי, כי אני ממילא לא מתכוון להשתמש בכונן הזה הרבה.


18 מאי, 2012 08:54 AM

17 מאי, 2012

Guy Sheffer

3arabi – Arabic chat to English translator

3arabi Logo

3arabi Logo

Hi  all,

As some might have noticed, Arabic speakers on the net use a form of writing called ‘Arabic chat‘ or 3arabi, which involves using Latin characters and Hindu-Arabic numerals to write words in Arabic. I wrote a small service called 3arabi that lets you translate this Arabic chat directly to English.

Apparently there are tools to do transliteration (converting Latin letters back to Arabic), and also translation. But nothing that does them both. That is why I wrote a small script that uses Google’s transliteration service and ‘Google Translate’. This does the job, but is not perfect, however, it does actually help me understand some messages.

The source is also available in GitHub (its in python). If anyone contributes better code I’ll merge it back to the service.

Thanks to Ira Abramov for hosting the service!

Thanks to Rajesh who wrote the transliteration API though after using it I moved to the javascript google tool with his help.

Thanks Muhammad Khatib who wrote Google Translate python API and for releasing it.

Enjoy,

Guy

Update: Google seem to be blocking the translation service, thinking its spam, if anyone knows how to contact them and asking them to lift that ban would be appreciated.


Full text

17 מאי, 2012 03:58 PM

Hamakor

‫אוגוסט פינגווין 2012‬

ביום שישי ה3/8/2012 ייערך כנס אוגוסט פנגווין – הכנס השנתי לתוכנה חופשית וקוד פתוח.
הכנס יתקיים באודיטוריום חיפה -אולם רפפורט, שד' הנשיא 138, מרכז הכרמל, חיפה.
שעות הכנס: 9:00 עד 14:00. 

אתר הכנס:
http://august.penguin.org.il
עמוד בוויקי

מרצים המעוניינים להעביר הרצאה בכנס מוזמנים לשלוח הצעה לוועד המקור board@hamakor.org.il או לוויקי בקטגוריה "תוכן הכנס".

מחיר הכניסה לכנס הוא 50 ש״ח (תשלום באמצעות PayPal). חברי וידידי העמותה זכאים להיכנס בחינם (בתנאי שחברותם בתוקף). עבור צעירים מתחת לגיל 18, סטודנטים וחיילים, מחיר הכניסה זהה למחיר התשלום השנתי של ידידות בעמותה, כך שנשמח לקבל אתכם כידידי העמותה.

Share

17 מאי, 2012 11:36 AM

16 מאי, 2012

Hetz Ben Hemo

‫הצפון ובחזרה, ופרטיות של הסלולר שלך‬

‫קוראי הבלוג הקבועים כבר קראו שרציתי לעבור לצפון מפאת חסכון ועוד סיבות, ואכן עברתי לצפון. לאן בדיוק? בשלב זה, להוריי. מדוע? אה, טוב ששאלתם. כאן בצפת נפתח לאחרונה בית ספר לרפואה, מה שהצליח תוך זמן קצר להקפיץ את המחירים פה בעשרות (ולעיתים במאות) אחוזים. פעם היה אפשר לשכור בצפת דירה של 3 חדרים בגודל של [...]‬

הטקסט המלא

16 מאי, 2012 02:23 PM

14 מאי, 2012

Ddorda

‫להתחבר לנטסטיק של סלקום/אורנג' באובונטו 12.04‬

שלום לכולם,

לאחרונה עדכנתי לאובונטו 12.04. לא אלאה אתכם בסיפור השדרוג שלי, אבל בסופו של יום מצאתי את עצמי עם מערכת חמודה ויציבה עם בעיה אחת עיקרית: אני לא מצליח להתחבר לאינטרנט הסלולרי של סלקום דרך הנטסטיק של חברת Alcatel שסלקום בדר"כ מחלקים (שד"א אורנג' משתמשים בדיוק באותו מוצר).

לאחר עלעול ברשת מצאתי את הפתרון וחשבתי שאולי הוא יוכל לעזור לעוד כמה חבר'ה שנתקלו באותה בעיה.

כל שעליכם לעשות הוא לערוך את הקובץ /etc/modules עם הרשאות root, במסוף (Alt+Ctrl+T) הדביקו את השורה הבאה:

sudo gedit /etc/modules

תתבקשו לכתוב את ססמתכם, הקלידו אותה, והקישו אנטר. ייפתח לכם עורך טקסט, הוסיפו לסוף הקובץ את שתי השורות הבאות:

usbserial
option

כדי להחיל את ההגדרות הפעילו מחדש את המחשב (מישהו מכיר פתרון נכון יותר?)

דור.

14 מאי, 2012 09:09 PM

Moshe Basanchig

Blogging for the .NET framework

A system I've been working on is based on the .NET framework. It seems that Mono and Apache on a web server is a pretty good combo, and I recommend everyone with a spare day or two to give it a try.

Anyway, I needed to run a blogging engine on that same server and have that blog support Hebrew and right-to-left languages. While there are several good blogging engines for .NET, not all would run on Mono and most doesn't do the RTL part good enough.
My first attempt was to use SubText, but getting rid of the SQL Server dependency and adding the RTL support became too much of a hassle. I picked SubText for it being notorious for its simplicity and elegance, but while I was ready to invest some customization time, it demanded too much of it.
My second attempt was BlogEngine.NET. What can I say - I fell for it almost immediately. The platform is versatile enough to support not only many RDBMS's, but it also allows storing the posts in XML files. Nonetheless, the translation to Hebrew wasn't complete and there was no RTL native theme for it. So I made one.

BlogEngine.NET is hosted on CodePlex and uses Mercurial for its source control. I had a fork of the project in no time, so I started making the required changes and created a new theme based on the default one. Since I don't want to maintain a fork of the project for eternity and since I want others to enjoy this new feature, I've sent a pull-request which was accepted yesterday. So starting from version 2.5.0.6, you can enjoy BlogEngine.NET for your Hebrew blog.

As always, it feels good to contribute back and to know that my code can be further enhanced by other developers.

Happy blogging.

14 מאי, 2012 10:45 AM

Shlomi Noach

Impact of foreign keys absence on replicating slaves

In this post I describe what happens when a slave's Foreign Key setup is different from that of the master. I'm in particular interested in a setup where the slave has a subset of the master's foreign keys, or no foreign keys at all. I wish to observe whether integrity holds.

Making the changes

Which foreign keys do we have and how do we drop them? If you want to do this by hand, well, good luck! Fortunately, common_schema provides with quite a few handy views and routines to assist us. Consider viewing the existing foreign keys on sakila:

master> SELECT create_statement FROM common_schema.sql_foreign_keys WHERE TABLE_SCHEMA='sakila';
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| create_statement                                                                                                                                                                                |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ALTER TABLE `sakila`.`address` ADD CONSTRAINT `fk_address_city` FOREIGN KEY (`city_id`) REFERENCES `sakila`.`city` (`city_id`) ON DELETE RESTRICT ON UPDATE CASCADE                             |
| ALTER TABLE `sakila`.`city` ADD CONSTRAINT `fk_city_country` FOREIGN KEY (`country_id`) REFERENCES `sakila`.`country` (`country_id`) ON DELETE RESTRICT ON UPDATE CASCADE                       |
| ALTER TABLE `sakila`.`customer` ADD CONSTRAINT `fk_customer_address` FOREIGN KEY (`address_id`) REFERENCES `sakila`.`address` (`address_id`) ON DELETE RESTRICT ON UPDATE CASCADE               |
| ALTER TABLE `sakila`.`customer` ADD CONSTRAINT `fk_customer_store` FOREIGN KEY (`store_id`) REFERENCES `sakila`.`store` (`store_id`) ON DELETE RESTRICT ON UPDATE CASCADE                       |
| ALTER TABLE `sakila`.`film` ADD CONSTRAINT `fk_film_language` FOREIGN KEY (`language_id`) REFERENCES `sakila`.`language` (`language_id`) ON DELETE RESTRICT ON UPDATE CASCADE                   |
| ALTER TABLE `sakila`.`film` ADD CONSTRAINT `fk_film_language_original` FOREIGN KEY (`original_language_id`) REFERENCES `sakila`.`language` (`language_id`) ON DELETE RESTRICT ON UPDATE CASCADE |
| ALTER TABLE `sakila`.`film_actor` ADD CONSTRAINT `fk_film_actor_actor` FOREIGN KEY (`actor_id`) REFERENCES `sakila`.`actor` (`actor_id`) ON DELETE RESTRICT ON UPDATE CASCADE                   |
| ALTER TABLE `sakila`.`film_actor` ADD CONSTRAINT `fk_film_actor_film` FOREIGN KEY (`film_id`) REFERENCES `sakila`.`film` (`film_id`) ON DELETE RESTRICT ON UPDATE CASCADE                       |
| ALTER TABLE `sakila`.`film_category` ADD CONSTRAINT `fk_film_category_category` FOREIGN KEY (`category_id`) REFERENCES `sakila`.`category` (`category_id`) ON DELETE RESTRICT ON UPDATE CASCADE |
| ALTER TABLE `sakila`.`film_category` ADD CONSTRAINT `fk_film_category_film` FOREIGN KEY (`film_id`) REFERENCES `sakila`.`film` (`film_id`) ON DELETE RESTRICT ON UPDATE CASCADE                 |
| ALTER TABLE `sakila`.`inventory` ADD CONSTRAINT `fk_inventory_film` FOREIGN KEY (`film_id`) REFERENCES `sakila`.`film` (`film_id`) ON DELETE RESTRICT ON UPDATE CASCADE                         |
| ALTER TABLE `sakila`.`inventory` ADD CONSTRAINT `fk_inventory_store` FOREIGN KEY (`store_id`) REFERENCES `sakila`.`store` (`store_id`) ON DELETE RESTRICT ON UPDATE CASCADE                     |
| ALTER TABLE `sakila`.`payment` ADD CONSTRAINT `fk_payment_customer` FOREIGN KEY (`customer_id`) REFERENCES `sakila`.`customer` (`customer_id`) ON DELETE RESTRICT ON UPDATE CASCADE             |
| ALTER TABLE `sakila`.`payment` ADD CONSTRAINT `fk_payment_rental` FOREIGN KEY (`rental_id`) REFERENCES `sakila`.`rental` (`rental_id`) ON DELETE SET NULL ON UPDATE CASCADE                     |
| ALTER TABLE `sakila`.`payment` ADD CONSTRAINT `fk_payment_staff` FOREIGN KEY (`staff_id`) REFERENCES `sakila`.`staff` (`staff_id`) ON DELETE RESTRICT ON UPDATE CASCADE                         |
| ALTER TABLE `sakila`.`rental` ADD CONSTRAINT `fk_rental_customer` FOREIGN KEY (`customer_id`) REFERENCES `sakila`.`customer` (`customer_id`) ON DELETE RESTRICT ON UPDATE CASCADE               |
| ALTER TABLE `sakila`.`rental` ADD CONSTRAINT `fk_rental_inventory` FOREIGN KEY (`inventory_id`) REFERENCES `sakila`.`inventory` (`inventory_id`) ON DELETE RESTRICT ON UPDATE CASCADE           |
| ALTER TABLE `sakila`.`rental` ADD CONSTRAINT `fk_rental_staff` FOREIGN KEY (`staff_id`) REFERENCES `sakila`.`staff` (`staff_id`) ON DELETE RESTRICT ON UPDATE CASCADE                           |
| ALTER TABLE `sakila`.`staff` ADD CONSTRAINT `fk_staff_address` FOREIGN KEY (`address_id`) REFERENCES `sakila`.`address` (`address_id`) ON DELETE RESTRICT ON UPDATE CASCADE                     |
| ALTER TABLE `sakila`.`staff` ADD CONSTRAINT `fk_staff_store` FOREIGN KEY (`store_id`) REFERENCES `sakila`.`store` (`store_id`) ON DELETE RESTRICT ON UPDATE CASCADE                             |
| ALTER TABLE `sakila`.`store` ADD CONSTRAINT `fk_store_address` FOREIGN KEY (`address_id`) REFERENCES `sakila`.`address` (`address_id`) ON DELETE RESTRICT ON UPDATE CASCADE                     |
| ALTER TABLE `sakila`.`store` ADD CONSTRAINT `fk_store_staff` FOREIGN KEY (`manager_staff_id`) REFERENCES `sakila`.`staff` (`staff_id`) ON DELETE RESTRICT ON UPDATE CASCADE                     |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

Most of the foreign key constraints use RESTRICT for DELETE (meaning you are not allowed to delete a parent row when children exist), and CASCADE for UPDATE (meaning changes to parent will propagate to children). This is good, since I want to test behavior of both RESTRICT and CASCADE.

OK, we wish to remove these constraints from the slave. To see what we are going to do, consider:

slave1> select drop_statement from common_schema.sql_foreign_keys where table_schema='sakila';
+-----------------------------------------------------------------------------------+
| drop_statement                                                                    |
+-----------------------------------------------------------------------------------+
| ALTER TABLE `sakila`.`address` DROP FOREIGN KEY `fk_address_city`                 |
| ALTER TABLE `sakila`.`city` DROP FOREIGN KEY `fk_city_country`                    |
| ALTER TABLE `sakila`.`customer` DROP FOREIGN KEY `fk_customer_address`            |
| ALTER TABLE `sakila`.`customer` DROP FOREIGN KEY `fk_customer_store`              |
| ALTER TABLE `sakila`.`film` DROP FOREIGN KEY `fk_film_language`                   |
| ALTER TABLE `sakila`.`film` DROP FOREIGN KEY `fk_film_language_original`          |
| ALTER TABLE `sakila`.`film_actor` DROP FOREIGN KEY `fk_film_actor_actor`          |
| ALTER TABLE `sakila`.`film_actor` DROP FOREIGN KEY `fk_film_actor_film`           |
| ALTER TABLE `sakila`.`film_category` DROP FOREIGN KEY `fk_film_category_category` |
| ALTER TABLE `sakila`.`film_category` DROP FOREIGN KEY `fk_film_category_film`     |
| ALTER TABLE `sakila`.`inventory` DROP FOREIGN KEY `fk_inventory_film`             |
| ALTER TABLE `sakila`.`inventory` DROP FOREIGN KEY `fk_inventory_store`            |
| ALTER TABLE `sakila`.`payment` DROP FOREIGN KEY `fk_payment_customer`             |
| ALTER TABLE `sakila`.`payment` DROP FOREIGN KEY `fk_payment_rental`               |
| ALTER TABLE `sakila`.`payment` DROP FOREIGN KEY `fk_payment_staff`                |
| ALTER TABLE `sakila`.`rental` DROP FOREIGN KEY `fk_rental_customer`               |
| ALTER TABLE `sakila`.`rental` DROP FOREIGN KEY `fk_rental_inventory`              |
| ALTER TABLE `sakila`.`rental` DROP FOREIGN KEY `fk_rental_staff`                  |
| ALTER TABLE `sakila`.`staff` DROP FOREIGN KEY `fk_staff_address`                  |
| ALTER TABLE `sakila`.`staff` DROP FOREIGN KEY `fk_staff_store`                    |
| ALTER TABLE `sakila`.`store` DROP FOREIGN KEY `fk_store_address`                  |
| ALTER TABLE `sakila`.`store` DROP FOREIGN KEY `fk_store_staff`                    |
+-----------------------------------------------------------------------------------+

To actually make the DROP, we use common_schema's eval():

slave1> call common_schema.eval("select drop_statement from common_schema.sql_foreign_keys where table_schema='sakila'");

eval() is a handy routine which invokes statements generated by the given query.

This concludes the setup part.

Tests will include:

  1. Attempting to delete a parent row
  2. Attempting to add an invalid child row
  3. Attempting to update parent row

I was thinking there would be a difference between the two binary log file formats: STATEMENT and ROW. But the tests I produced showed no difference.

Tests

Attempting to delete parent row:

master> delete from actor where actor_id=1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`sakila`.`film_actor`, CONSTRAINT `fk_film_actor_actor` FOREIGN KEY (`actor_id`) REFERENCES `actor` (`actor_id`) ON UPDATE CASCADE)

slave1> select * from actor where actor_id=1;
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update         |
+----------+------------+-----------+---------------------+
|        1 | PENELOPE   | GUINESS   | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+

Good: the master refused the DELETE, and no DELETE occurred on slave. Integrity is intact.

Attempting to add an invalid child row:

master> insert into film_actor (actor_id, film_id, last_update) values (9999, 1, NOW());
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`sakila`.`film_actor`, CONSTRAINT `fk_film_actor_actor` FOREIGN KEY (`actor_id`) REFERENCES `actor` (`actor_id`) ON UPDATE CASCADE)

slave> select * from film_actor where actor_id=9999;
Empty set (0.00 sec)

Integrity is still intact.

Attempting to update parent row: there is nothing invalid about this operation. I'm wondering whether changes are CASCADEd on slave as well as on master:

master> update actor set actor_id=999 where actor_id=199;

master> select count(*) from film_actor where actor_id=999;
+----------+
| count(*) |
+----------+
|       15 |
+----------+

The 999 value wasn't there before on the master, so this verifies the CASCADE works on master. As for slave:

slave> select count(*) from actor where actor_id=999;
+----------+
| count(*) |
+----------+
|        1 |
+----------+

slave> select count(*) from film_actor where actor_id=999;
+----------+
| count(*) |
+----------+
|        0 |
+----------+

Bummer! The actor's row was updated, but cascading did not work on slave.

This is actually documented. However, the documentation only relates to the issue of slave tables being MyISAM. The problem occurs even when the slave tables are InnoDB, and have no foreign key constraints.

Conclusion

My personal interest in the scenario is due to something I'm working on, I'll elaborate on a future post. People sometime hope to get rid of foreign keys, and might wonder whether replication performance would boost having constraints removed on slaves.

When slave does not enforce foreign keys, you cannot rely on integrity with cascading constraints. An ugly patch might be to use triggers so as to simulate their behavior. Performance wise this is very bad.

14 מאי, 2012 05:52 AM